Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove bogus XBT_PRIVATE
[simgrid.git] / src / xbt / ex.c
index 1017b5f..0a4e65e 100644 (file)
@@ -1,6 +1,8 @@
 /* ex - Exception Handling                                                  */
 
 /* ex - Exception Handling                                                  */
 
-/*  Copyright (c) 2005-2010 The SimGrid team                                */
+/* Copyright (c) 2005-2015. The SimGrid Team.
+ * All rights reserved.                                                     */
+
 /*  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>       */
 /*  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>         */
 /*  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>           */
 /*  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>       */
 /*  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>         */
 /*  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>           */
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "portable.h"           /* execinfo when available */
+#include "src/internal_config.h"           /* execinfo when available */
 #include "xbt/ex.h"
 #include "xbt/str.h"
 #include "xbt/ex.h"
 #include "xbt/str.h"
-#include "xbt_modinter.h"       /* backtrace initialization headers */
-
-#include "xbt/ex_interface.h"
+#include "xbt/synchro_core.h"
+#include "src/xbt_modinter.h"       /* backtrace initialization headers */
 
 
-#undef HAVE_BACKTRACE
-#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
-# define HAVE_BACKTRACE 1       /* Hello linux box */
-#endif
-
-#if defined(_XBT_WIN32) && defined(_M_IX86) && !defined(__GNUC__)
-# define HAVE_BACKTRACE 1       /* Hello x86 windows box */
-#endif
+#include "src/xbt/ex_interface.h"
+#include "simgrid/sg_config.h"  /* Configuration mechanism of SimGrid */
 
 
+#include "simgrid/simix.h" /* SIMIX_process_self_get_name() */
 
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex, xbt, "Exception mecanism");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex, xbt, "Exception mechanism");
 
 XBT_EXPORT_NO_IMPORT(const xbt_running_ctx_t) __xbt_ex_ctx_initializer = XBT_RUNNING_CTX_INITIALIZER;
 
 
 XBT_EXPORT_NO_IMPORT(const xbt_running_ctx_t) __xbt_ex_ctx_initializer = XBT_RUNNING_CTX_INITIALIZER;
 
@@ -74,7 +70,7 @@ xbt_running_ctx_t *__xbt_ex_ctx_default(void)
      real life and in simulation when using threads to implement the simulation
      processes (ie, with pthreads and on windows).
 
      real life and in simulation when using threads to implement the simulation
      processes (ie, with pthreads and on windows).
 
-     It also gets overriden in xbt/context.c when using ucontextes (as well as
+     It also gets overriden in xbt/context.c when using ucontexts (as well as
      in Java for now, but after the java overhaul, it will get cleaned out)
    */
   static xbt_running_ctx_t ctx = XBT_RUNNING_CTX_INITIALIZER;
      in Java for now, but after the java overhaul, it will get cleaned out)
    */
   static xbt_running_ctx_t ctx = XBT_RUNNING_CTX_INITIALIZER;
@@ -93,20 +89,15 @@ void xbt_backtrace_display(xbt_ex_t * e)
   if (e->used == 0) {
     fprintf(stderr, "(backtrace not set)\n");
   } else {
   if (e->used == 0) {
     fprintf(stderr, "(backtrace not set)\n");
   } else {
-    int i;
-
-    fprintf(stderr, "Backtrace (displayed in thread %p):\n",
-            (void *) xbt_thread_self());
-    for (i = 1; i < e->used; i++)       /* no need to display "xbt_backtrace_display" */
+    fprintf(stderr, "Backtrace (displayed in process %s):\n", SIMIX_process_self_get_name());
+    for (int i = 1; i < e->used; i++)       /* no need to display "xbt_backtrace_display" */
       fprintf(stderr, "---> %s\n", e->bt_strings[i] + 4);
   }
 
   /* don't fool xbt_ex_free with uninitialized msg field */
   e->msg = NULL;
       fprintf(stderr, "---> %s\n", e->bt_strings[i] + 4);
   }
 
   /* don't fool xbt_ex_free with uninitialized msg field */
   e->msg = NULL;
-  e->remote = 0;
   xbt_ex_free(*e);
 #else
   xbt_ex_free(*e);
 #else
-
   XBT_ERROR("No backtrace on this arch");
 #endif
 }
   XBT_ERROR("No backtrace on this arch");
 #endif
 }
@@ -119,56 +110,74 @@ void xbt_backtrace_display_current(void)
   xbt_backtrace_display(&e);
 }
 
   xbt_backtrace_display(&e);
 }
 
-#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
-# include "backtrace_linux.c"
-#elif (defined(_XBT_WIN32) && defined (_M_IX86)) && !defined(__GNUC__)
-# include "backtrace_windows.c"
+#if HAVE_BACKTRACE && HAVE_EXECINFO_H && HAVE_POPEN && defined(ADDR2LINE)
+# include "src/xbt/backtrace_linux.c"
 #else
 #else
-# include "backtrace_dummy.c"
+# include "src/xbt/backtrace_dummy.c"
 #endif
 
 /** @brief shows an exception content and the associated stack if available */
 void xbt_ex_display(xbt_ex_t * e)
 {
   char *thrower = NULL;
 #endif
 
 /** @brief shows an exception content and the associated stack if available */
 void xbt_ex_display(xbt_ex_t * e)
 {
   char *thrower = NULL;
+  if (e->pid != xbt_getpid())
+    thrower = bprintf(" on process %d",e->pid);
 
 
-  if (e->remote)
-    thrower = bprintf(" on host %s(%d)", e->host, e->pid);
-
-  fprintf(stderr,
-          "** SimGrid: UNCAUGHT EXCEPTION received on %s(%d): category: %s; value: %d\n"
+  fprintf(stderr, "** SimGrid: UNCAUGHT EXCEPTION received on %s(%d): category: %s; value: %d\n"
           "** %s\n"
           "** Thrown by %s()%s\n",
           "** %s\n"
           "** Thrown by %s()%s\n",
-          xbt_binary_name, xbt_getpid(),
-          xbt_ex_catname(e->category), e->value, e->msg,
+          xbt_binary_name, xbt_getpid(), xbt_ex_catname(e->category), e->value, e->msg,
           e->procname, thrower ? thrower : " in this process");
   XBT_CRITICAL("%s", e->msg);
   xbt_free(thrower);
 
           e->procname, thrower ? thrower : " in this process");
   XBT_CRITICAL("%s", e->msg);
   xbt_free(thrower);
 
-  if (!e->remote && !e->bt_strings)
+  if (xbt_initialized==0 || smx_cleaned) {
+    fprintf(stderr, "Ouch. SimGrid is not initialized yet, or already closing. No backtrace available.\n");
+    return; /* Not started yet or already closing. Trying to generate a backtrace would probably fail */
+  }
+
+  if (!e->bt_strings)
     xbt_ex_setup_backtrace(e);
 
 #ifdef HAVE_BACKTRACE
   if (e->used && e->bt_strings) {
     /* We have everything to build neat backtraces */
     int i;
     xbt_ex_setup_backtrace(e);
 
 #ifdef HAVE_BACKTRACE
   if (e->used && e->bt_strings) {
     /* We have everything to build neat backtraces */
     int i;
+    int cutpath = 0;
+    TRY { // We don't want to have an exception while checking how to deal with the one we already have, do we?
+      cutpath = xbt_cfg_get_boolean("exception/cutpath");
+    } CATCH_ANONYMOUS { }
 
     fprintf(stderr, "\n");
 
     fprintf(stderr, "\n");
-    for (i = 0; i < e->used; i++)
-      fprintf(stderr, "%s\n", e->bt_strings[i]);
-
+    for (i = 0; i < e->used; i++) {
+        
+      if (cutpath) {
+        char* p = e->bt_strings[i];
+        xbt_str_rtrim(p, ":0123456789");
+        char* filename = strrchr(p, '/')+1;
+        char* end_of_message  = strrchr(p, ' ');
+
+        int length = strlen(p)-strlen(end_of_message);
+        char* dest = malloc(length);
+
+        memcpy(dest, &p[0], length);
+        dest[length] = 0;
+
+        fprintf(stderr, "%s %s\n", dest, filename);
+
+        free(dest);
+      }
+      else {
+        fprintf(stderr, "%s\n", e->bt_strings[i]);
+      }
+    }
   } else
 #endif
   } else
 #endif
-  {
-    fprintf(stderr,
-            "\n"
-            "**   In %s() at %s:%d\n"
-            "**   (no backtrace available)\n",
-            e->func, e->file, e->line);
-  }
+    fprintf(stderr, "\n"
+        "**   In %s() at %s:%d\n"
+        "**   (no backtrace available)\n", e->func, e->file, e->line);
 }
 
 }
 
-
 /* default __ex_terminate callback function */
 void __xbt_ex_terminate_default(xbt_ex_t * e)
 {
 /* default __ex_terminate callback function */
 void __xbt_ex_terminate_default(xbt_ex_t * e)
 {
@@ -178,28 +187,17 @@ void __xbt_ex_terminate_default(xbt_ex_t * e)
 
 /* the externally visible API */
 XBT_EXPORT_NO_IMPORT(xbt_running_ctx_fetcher_t) __xbt_running_ctx_fetch = &__xbt_ex_ctx_default;
 
 /* the externally visible API */
 XBT_EXPORT_NO_IMPORT(xbt_running_ctx_fetcher_t) __xbt_running_ctx_fetch = &__xbt_ex_ctx_default;
-XBT_EXPORT_NO_IMPORT(ex_term_cb_t) __xbt_ex_terminate =
-    &__xbt_ex_terminate_default;
-
+XBT_EXPORT_NO_IMPORT(ex_term_cb_t) __xbt_ex_terminate = &__xbt_ex_terminate_default;
 
 void xbt_ex_free(xbt_ex_t e)
 {
 
 void xbt_ex_free(xbt_ex_t e)
 {
-  int i;
-
   free(e.msg);
   free(e.msg);
-  if (e.remote) {
-    free(e.procname);
-    free(e.file);
-    free(e.func);
-    free(e.host);
-  }
 
   if (e.bt_strings) {
 
   if (e.bt_strings) {
-    for (i = 0; i < e.used; i++)
+    for (int i = 0; i < e.used; i++)
       free(e.bt_strings[i]);
     free(e.bt_strings);
   }
       free(e.bt_strings[i]);
     free(e.bt_strings);
   }
-  /* memset(e,0,sizeof(xbt_ex_t)); */
 }
 
 /** \brief returns a short name for the given exception category */
 }
 
 /** \brief returns a short name for the given exception category */
@@ -232,11 +230,12 @@ const char *xbt_ex_catname(xbt_errcat_t cat)
     return "tracing error";
   case io_error:
     return "io error";
     return "tracing error";
   case io_error:
     return "io error";
+  case vm_error:
+    return "vm error";
   }
   return "INVALID ERROR";
 }
 
   }
   return "INVALID ERROR";
 }
 
-
 #ifdef SIMGRID_TEST
 #include <stdio.h>
 #include "xbt/ex.h"
 #ifdef SIMGRID_TEST
 #include <stdio.h>
 #include "xbt/ex.h"
@@ -259,8 +258,7 @@ XBT_TEST_UNIT("controlflow", test_controlflow, "basic nested control flow")
         xbt_test_fail("M2: n=%d (!= 2)", n);
       n++;
       THROWF(unknown_error, 0, "something");
         xbt_test_fail("M2: n=%d (!= 2)", n);
       n++;
       THROWF(unknown_error, 0, "something");
-    }
-    CATCH(ex) {
+    } CATCH(ex) {
       if (n != 3)
         xbt_test_fail("M3: n=%d (!= 3)", n);
       n++;
       if (n != 3)
         xbt_test_fail("M3: n=%d (!= 3)", n);
       n++;
@@ -272,8 +270,7 @@ XBT_TEST_UNIT("controlflow", test_controlflow, "basic nested control flow")
         xbt_test_fail("M2: n=%d (!= 5)", n);
       n++;
       THROWF(unknown_error, 0, "something");
         xbt_test_fail("M2: n=%d (!= 5)", n);
       n++;
       THROWF(unknown_error, 0, "something");
-    }
-    CATCH_ANONYMOUS {
+    } CATCH_ANONYMOUS {
       if (n != 6)
         xbt_test_fail("M3: n=%d (!= 6)", n);
       n++;
       if (n != 6)
         xbt_test_fail("M3: n=%d (!= 6)", n);
       n++;
@@ -281,8 +278,7 @@ XBT_TEST_UNIT("controlflow", test_controlflow, "basic nested control flow")
       n++;
     }
     xbt_test_fail("MX: n=%d (shouldn't reach this point)", n);
       n++;
     }
     xbt_test_fail("MX: n=%d (shouldn't reach this point)", n);
-  }
-  CATCH(ex) {
+  } CATCH(ex) {
     if (n != 7)
       xbt_test_fail("M4: n=%d (!= 7)", n);
     n++;
     if (n != 7)
       xbt_test_fail("M4: n=%d (!= 7)", n);
     n++;
@@ -298,8 +294,7 @@ XBT_TEST_UNIT("value", test_value, "exception value passing")
 
   TRY {
     THROWF(unknown_error, 2, "toto");
 
   TRY {
     THROWF(unknown_error, 2, "toto");
-  }
-  CATCH(ex) {
+  } CATCH(ex) {
     xbt_test_add("exception value passing");
     if (ex.category != unknown_error)
       xbt_test_fail("category=%d (!= 1)", (int)ex.category);
     xbt_test_add("exception value passing");
     if (ex.category != unknown_error)
       xbt_test_fail("category=%d (!= 1)", (int)ex.category);
@@ -315,7 +310,7 @@ XBT_TEST_UNIT("variables", test_variables, "variable value preservation")
 {
   xbt_ex_t ex;
   int r1;
 {
   xbt_ex_t ex;
   int r1;
-  int _XBT_GNUC_UNUSED r2;
+  int XBT_ATTRIB_UNUSED r2;
   int v1;
   volatile int v2;
 
   int v1;
   volatile int v2;
 
@@ -324,8 +319,7 @@ XBT_TEST_UNIT("variables", test_variables, "variable value preservation")
     r2 = 5678;
     v2 = 5678;
     THROWF(unknown_error, 0, "toto");
     r2 = 5678;
     v2 = 5678;
     THROWF(unknown_error, 0, "toto");
-  }
-  CATCH(ex) {
+  } CATCH(ex) {
     xbt_test_add("variable preservation");
     if (r1 != 1234)
       xbt_test_fail("r1=%d (!= 1234)", r1);
     xbt_test_add("variable preservation");
     if (r1 != 1234)
       xbt_test_fail("r1=%d (!= 1234)", r1);
@@ -356,8 +350,7 @@ XBT_TEST_UNIT("cleanup", test_cleanup, "cleanup handling")
     if (v1 != 5678)
       xbt_test_fail("v1 = %d (!= 5678)", v1);
     c = 1;
     if (v1 != 5678)
       xbt_test_fail("v1 = %d (!= 5678)", v1);
     c = 1;
-  }
-  CATCH(ex) {
+  } CATCH(ex) {
     if (v1 != 5678)
       xbt_test_fail("v1 = %d (!= 5678)", v1);
     if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg, "blah")))
     if (v1 != 5678)
       xbt_test_fail("v1 = %d (!= 5678)", v1);
     if (!(ex.category == 1 && ex.value == 2 && !strcmp(ex.msg, "blah")))
@@ -368,7 +361,6 @@ XBT_TEST_UNIT("cleanup", test_cleanup, "cleanup handling")
     xbt_test_fail("xbt_ex_free not executed");
 }
 
     xbt_test_fail("xbt_ex_free not executed");
 }
 
-
 /*
  * The following is the example included in the documentation. It's a good
  * idea to check its syntax even if we don't try to run it.
 /*
  * The following is the example included in the documentation. It's a good
  * idea to check its syntax even if we don't try to run it.
@@ -382,44 +374,13 @@ static char *mallocex(int size)
 #define SMALLAMOUNT 10
 #define TOOBIG 100000000
 
 #define SMALLAMOUNT 10
 #define TOOBIG 100000000
 
-#if 0                           /* this contains syntax errors, actually */
-static void bad_example(void)
-{
-  struct {
-    char *first;
-  } *globalcontext;
-  ex_t ex;
-
-  /* BAD_EXAMPLE */
-  TRY {
-    char *cp1, *cp2, *cp3;
-
-    cp1 = mallocex(SMALLAMOUNT);
-    globalcontext->first = cp1;
-    cp2 = mallocex(TOOBIG);
-    cp3 = mallocex(SMALLAMOUNT);
-    strcpy(cp1, "foo");
-    strcpy(cp2, "bar");
-  }
-  TRY_CLEANUP {
-    free(cp3);
-    free(cp2);
-    free(cp1);
-  }
-  CATCH_ANONYMOUS {
-    printf("cp3=%s", cp3);
-    RETHROW;
-  }
-  /* end_of_bad_example */
-}
-#endif
 typedef struct {
   char *first;
 } global_context_t;
 
 static void good_example(void)
 {
 typedef struct {
   char *first;
 } global_context_t;
 
 static void good_example(void)
 {
-  global_context_t *global_context = malloc(sizeof(global_context_t));
+  global_context_t *global_context = xbt_malloc(sizeof(global_context_t));
 
   /* GOOD_EXAMPLE */
   {                             /*01 */
 
   /* GOOD_EXAMPLE */
   {                             /*01 */