Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
split windows and linux backtrace setup out of the main exception file
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 7 Jan 2008 22:39:07 +0000 (22:39 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 7 Jan 2008 22:39:07 +0000 (22:39 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@5174 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/Makefile.am
src/Makefile.in
src/ex_unit.c
src/simgrid_units_main.c
src/xbt/backtrace_linux.c [new file with mode: 0644]
src/xbt/backtrace_windows.c [new file with mode: 0644]
src/xbt/ex.c

index c321a1c..a9f109c 100644 (file)
@@ -36,6 +36,7 @@ EXTRA_DIST= \
         xbt/xbt_jcontext.h \
        xbt/log_private.h \
        xbt/ex_interface.h \
         xbt/xbt_jcontext.h \
        xbt/log_private.h \
        xbt/ex_interface.h \
+        xbt/backtrace_linux.c xbt/backtrace_windows.c \
         \
        surf/maxmin_private.h \
        surf/trace_mgr_private.h \
         \
        surf/maxmin_private.h \
        surf/trace_mgr_private.h \
@@ -320,6 +321,7 @@ libsimgrid_la_SOURCES = $(XBT_SRC) $(SURF_SRC) $(GTNETS_USED) $(SDP_SRC) \
                         $(MSG_SRC) $(SIMDAG_SRC) \
                        $(GRAS_COMMON_SRC) $(GRAS_SG_SRC) $(AMOK_SRC)
 libsimgrid_la_LDFLAGS = -no-undefined $(VERSION_INFO) @SIMGRID_DEP@ @LD_DYNAMIC_FLAGS@ -lm
                         $(MSG_SRC) $(SIMDAG_SRC) \
                        $(GRAS_COMMON_SRC) $(GRAS_SG_SRC) $(AMOK_SRC)
 libsimgrid_la_LDFLAGS = -no-undefined $(VERSION_INFO) @SIMGRID_DEP@ @LD_DYNAMIC_FLAGS@ -lm
+# -Wl,--entry -Wl,simgrid_version
 
 # Please do not add -no-undefined to libsmpi_la_LDFLAGS:
 # smpi_simulated_main is indeed defined in user code, and undef in the
 
 # Please do not add -no-undefined to libsmpi_la_LDFLAGS:
 # smpi_simulated_main is indeed defined in user code, and undef in the
index 239fc1b..3f5b683 100644 (file)
@@ -142,16 +142,17 @@ am__libsimgrid_la_SOURCES_DIST = xbt/snprintf.c xbt/xbt_str.c \
        simix/smx_action.c simix/smx_synchro.c xbt/xbt_context.c \
        msg/msg_config.c msg/task.c msg/host.c msg/m_process.c \
        msg/gos.c msg/global.c msg/environment.c msg/deployment.c \
        simix/smx_action.c simix/smx_synchro.c xbt/xbt_context.c \
        msg/msg_config.c msg/task.c msg/host.c msg/m_process.c \
        msg/gos.c msg/global.c msg/environment.c msg/deployment.c \
-       simdag/sd_global.c simdag/sd_link.c simdag/sd_task.c \
-       simdag/sd_workstation.c gras/gras.c gras/Transport/transport.c \
-       gras/Transport/transport_private.h gras/Msg/gras_msg_mod.c \
-       gras/Msg/gras_msg_types.c gras/Msg/gras_msg_exchange.c \
-       gras/Msg/gras_msg_listener.c gras/Msg/rpc.c gras/Msg/timer.c \
-       gras/Msg/msg_interface.h gras/Msg/msg_private.h \
-       gras/Virtu/process.c gras/Virtu/gras_module.c \
-       gras/DataDesc/ddt_create.c gras/DataDesc/ddt_convert.c \
-       gras/DataDesc/ddt_exchange.c gras/DataDesc/cbps.c \
-       gras/DataDesc/datadesc.c gras/DataDesc/datadesc_interface.h \
+       msg/msg_mailbox.c simdag/sd_global.c simdag/sd_link.c \
+       simdag/sd_task.c simdag/sd_workstation.c gras/gras.c \
+       gras/Transport/transport.c gras/Transport/transport_private.h \
+       gras/Msg/gras_msg_mod.c gras/Msg/gras_msg_types.c \
+       gras/Msg/gras_msg_exchange.c gras/Msg/gras_msg_listener.c \
+       gras/Msg/rpc.c gras/Msg/timer.c gras/Msg/msg_interface.h \
+       gras/Msg/msg_private.h gras/Virtu/process.c \
+       gras/Virtu/gras_module.c gras/DataDesc/ddt_create.c \
+       gras/DataDesc/ddt_convert.c gras/DataDesc/ddt_exchange.c \
+       gras/DataDesc/cbps.c gras/DataDesc/datadesc.c \
+       gras/DataDesc/datadesc_interface.h \
        gras/DataDesc/datadesc_private.h gras/DataDesc/ddt_parse.c \
        gras/DataDesc/ddt_parse.yy.c gras/DataDesc/ddt_parse.yy.h \
        gras/Transport/sg_transport.c \
        gras/DataDesc/datadesc_private.h gras/DataDesc/ddt_parse.c \
        gras/DataDesc/ddt_parse.yy.c gras/DataDesc/ddt_parse.yy.h \
        gras/Transport/sg_transport.c \
@@ -180,7 +181,7 @@ am__objects_12 = smx_global.lo smx_deployment.lo smx_config.lo \
        smx_synchro.lo
 am__objects_13 = xbt_context.lo
 am__objects_14 = msg_config.lo task.lo host.lo m_process.lo gos.lo \
        smx_synchro.lo
 am__objects_13 = xbt_context.lo
 am__objects_14 = msg_config.lo task.lo host.lo m_process.lo gos.lo \
-       global.lo environment.lo deployment.lo
+       global.lo environment.lo deployment.lo msg_mailbox.lo
 am__objects_15 = sd_global.lo sd_link.lo sd_task.lo sd_workstation.lo
 am__objects_16 = xbt_sg_synchro.lo xbt_sg_time.lo
 am__objects_17 = sg_transport.lo transport_plugin_sg.lo sg_emul.lo \
 am__objects_15 = sd_global.lo sd_link.lo sd_task.lo sd_workstation.lo
 am__objects_16 = xbt_sg_synchro.lo xbt_sg_time.lo
 am__objects_17 = sg_transport.lo transport_plugin_sg.lo sg_emul.lo \
@@ -396,7 +397,8 @@ EXTRA_DIST = portable.h xbt/mallocator_private.h xbt/dynar_private.h \
        xbt/graph_private.h xbt/graphxml_parse.c xbt/graphxml.l \
        xbt/graphxml.c xbt/graphxml.dtd xbt/xbt_context_private.h \
        xbt/xbt_context_factory.h xbt/xbt_jcontext.h xbt/log_private.h \
        xbt/graph_private.h xbt/graphxml_parse.c xbt/graphxml.l \
        xbt/graphxml.c xbt/graphxml.dtd xbt/xbt_context_private.h \
        xbt/xbt_context_factory.h xbt/xbt_jcontext.h xbt/log_private.h \
-       xbt/ex_interface.h surf/maxmin_private.h \
+       xbt/ex_interface.h xbt/backtrace_linux.c \
+       xbt/backtrace_windows.c surf/maxmin_private.h \
        surf/trace_mgr_private.h surf/surf_private.h \
        surf/cpu_private.h surf/workstation_private.h \
        surf/surf_timer_private.h surf/surfxml_parse.c \
        surf/trace_mgr_private.h surf/surf_private.h \
        surf/cpu_private.h surf/workstation_private.h \
        surf/surf_timer_private.h surf/surfxml_parse.c \
@@ -533,7 +535,7 @@ SMPI_SRC = \
 
 MSG_SRC = msg/msg_config.c \
   msg/task.c msg/host.c msg/m_process.c msg/gos.c \
 
 MSG_SRC = msg/msg_config.c \
   msg/task.c msg/host.c msg/m_process.c msg/gos.c \
-  msg/global.c msg/environment.c msg/deployment.c 
+  msg/global.c msg/environment.c msg/deployment.c msg/msg_mailbox.c
 
 JMSG_C_SRC = \
   xbt/xbt_jcontext.c \
 
 JMSG_C_SRC = \
   xbt/xbt_jcontext.c \
@@ -821,6 +823,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallocator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxmin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg_config.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mallocator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxmin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msg_mailbox.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network_gtnets.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peermanagement.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/network_gtnets.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peermanagement.Plo@am__quote@
@@ -1586,6 +1589,13 @@ deployment.lo: msg/deployment.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o deployment.lo `test -f 'msg/deployment.c' || echo '$(srcdir)/'`msg/deployment.c
 
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o deployment.lo `test -f 'msg/deployment.c' || echo '$(srcdir)/'`msg/deployment.c
 
+msg_mailbox.lo: msg/msg_mailbox.c
+@am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT msg_mailbox.lo -MD -MP -MF $(DEPDIR)/msg_mailbox.Tpo -c -o msg_mailbox.lo `test -f 'msg/msg_mailbox.c' || echo '$(srcdir)/'`msg/msg_mailbox.c
+@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/msg_mailbox.Tpo $(DEPDIR)/msg_mailbox.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='msg/msg_mailbox.c' object='msg_mailbox.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o msg_mailbox.lo `test -f 'msg/msg_mailbox.c' || echo '$(srcdir)/'`msg/msg_mailbox.c
+
 sd_global.lo: simdag/sd_global.c
 @am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sd_global.lo -MD -MP -MF $(DEPDIR)/sd_global.Tpo -c -o sd_global.lo `test -f 'simdag/sd_global.c' || echo '$(srcdir)/'`simdag/sd_global.c
 @am__fastdepCC_TRUE@   mv -f $(DEPDIR)/sd_global.Tpo $(DEPDIR)/sd_global.Plo
 sd_global.lo: simdag/sd_global.c
 @am__fastdepCC_TRUE@   $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sd_global.lo -MD -MP -MF $(DEPDIR)/sd_global.Tpo -c -o sd_global.lo `test -f 'simdag/sd_global.c' || echo '$(srcdir)/'`simdag/sd_global.c
 @am__fastdepCC_TRUE@   mv -f $(DEPDIR)/sd_global.Tpo $(DEPDIR)/sd_global.Plo
index 261a8d9..2a50f99 100644 (file)
@@ -8,7 +8,7 @@
 /* GENERATED FILE, DO NOT EDIT */
 /*******************************/
 
 /* GENERATED FILE, DO NOT EDIT */
 /*******************************/
 
-# 419 "xbt/ex.c" 
+# 194 "xbt/ex.c" 
 #include <stdio.h>
 #include "xbt/ex.h"
 
 #include <stdio.h>
 #include "xbt/ex.h"
 
index 7e5de8d..f65097e 100644 (file)
@@ -57,10 +57,6 @@ extern xbt_test_unit_t _xbt_current_unit;
     void test_config_use(void);
   /* SGU: END FILE */
 
     void test_config_use(void);
   /* SGU: END FILE */
 
-  /* SGU: BEGIN FILE ./xbt/cunit.c */
-    void test_expected_failure(void);
-  /* SGU: END FILE */
-
 
 /*******************************/
 /* GENERATED FILE, DO NOT EDIT */
 
 /*******************************/
 /* GENERATED FILE, DO NOT EDIT */
@@ -71,6 +67,8 @@ int main(int argc, char *argv[]) {
   char selection[1024];
   int i;
 
   char selection[1024];
   int i;
 
+  int res;
+
   /* SGU: BEGIN SUITES DECLARATION */
     /* SGU: BEGIN FILE xbt/cunit.c */
       suite = xbt_test_suite_by_name("cunit","Testsuite mechanism autotest");
   /* SGU: BEGIN SUITES DECLARATION */
     /* SGU: BEGIN FILE xbt/cunit.c */
       suite = xbt_test_suite_by_name("cunit","Testsuite mechanism autotest");
@@ -128,11 +126,6 @@ int main(int argc, char *argv[]) {
       xbt_test_suite_push(suite, "use", test_config_use, "Data retrieving tests");
     /* SGU: END FILE */
 
       xbt_test_suite_push(suite, "use", test_config_use, "Data retrieving tests");
     /* SGU: END FILE */
 
-    /* SGU: BEGIN FILE ./xbt/cunit.c */
-      suite = xbt_test_suite_by_name("cunit","Testsuite mechanism autotest");
-      xbt_test_suite_push(suite, "expect", test_expected_failure, "expected failures");
-    /* SGU: END FILE */
-
   /* SGU: END SUITES DECLARATION */
       
   xbt_init(&argc,argv);
   /* SGU: END SUITES DECLARATION */
       
   xbt_init(&argc,argv);
@@ -180,7 +173,9 @@ int main(int argc, char *argv[]) {
     }
   /* Got all my tests to do */
       
     }
   /* Got all my tests to do */
       
-  return xbt_test_run(selection);
+  res = xbt_test_run(selection);
+  xbt_exit();
+  return res;
 }
 /*******************************/
 /* GENERATED FILE, DO NOT EDIT */
 }
 /*******************************/
 /* GENERATED FILE, DO NOT EDIT */
diff --git a/src/xbt/backtrace_linux.c b/src/xbt/backtrace_linux.c
new file mode 100644 (file)
index 0000000..e517242
--- /dev/null
@@ -0,0 +1,244 @@
+/* $Id: ex.c 5173 2008-01-07 22:10:52Z mquinson $ */
+
+/* backtrace_linux - backtrace displaying on linux platform                 */
+/* This file is included by ex.c on need (have execinfo.h, popen & addrline)*/
+
+/*  Copyright (c) 2007 The SimGrid team                                     */
+/*  All rights reserved.                                                    */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+extern char **environ; /* the environment, as specified by the opengroup */
+
+void xbt_ex_setup_backtrace(xbt_ex_t *e)  {
+  int i;
+  /* to get the backtrace from the libc */
+  char **backtrace = backtrace_symbols (e->bt, e->used);
+  
+  /* To build the commandline of addr2line */
+  char *cmd, *curr;
+  
+  /* to extract the addresses from the backtrace */
+  char **addrs=xbt_new(char*,e->used);
+  char buff[256],*p;
+  
+  /* To read the output of addr2line */
+  FILE *pipe;
+  char line_func[1024],line_pos[1024];
+
+  /* size (in char) of pointers on this arch */
+  int addr_len=0;
+
+  /* To search for the right executable path when not trivial */
+  struct stat stat_buf;
+  char *binary_name = NULL;
+   
+  /* Some arches only have stubs of backtrace, no implementation (hppa comes to mind) */
+  if (!e->used)
+     return;
+   
+  /* build the commandline */
+  if (stat(xbt_binary_name,&stat_buf)) {
+    /* Damn. binary not in current dir. We'll have to dig the PATH to find it */
+    int i;
+    for (i=0; environ[i]; i++) {
+      if (!strncmp("PATH=",environ[i], 5)) {   
+       xbt_dynar_t path=xbt_str_split(environ[i] + 5, ":");
+       unsigned int cpt;
+       char *data;
+       xbt_dynar_foreach(path, cpt, data) {
+         if (binary_name)
+           free(binary_name);
+         binary_name = bprintf("%s/%s",data,xbt_binary_name);
+         if (!stat(binary_name,&stat_buf)) {
+           /* Found. */
+           DEBUG1("Looked in the PATH for the binary. Found %s",binary_name);
+           xbt_dynar_free(&path);
+           break;
+         } 
+       }
+       if (stat(binary_name,&stat_buf)) {
+         /* not found */
+         e->used = 1;
+         e->bt_strings = xbt_new(char*,1);
+         e->bt_strings[0] = bprintf("(binary '%s' not found the path)",xbt_binary_name);
+         return;
+       }
+       xbt_dynar_free(&path);
+       break;
+      }        
+    }
+  } else {
+    binary_name = xbt_strdup(xbt_binary_name);
+  }      
+  cmd = curr = xbt_new(char,strlen(ADDR2LINE)+25+strlen(binary_name)+32*e->used);
+   
+  curr += sprintf(curr,"%s -f -e %s ",ADDR2LINE,binary_name);
+  free(binary_name);
+   
+  for (i=0; i<e->used;i++) {
+    /* retrieve this address */
+    DEBUG2("Retrieving address number %d from '%s'", i, backtrace[i]);
+    snprintf(buff,256,"%s",strchr(backtrace[i],'[')+1);
+    p=strchr(buff,']');
+    *p='\0';
+    if (strcmp(buff,"(nil)"))
+       addrs[i]=bprintf("%s", buff);
+    else
+       addrs[i]=bprintf("0x0");
+    DEBUG3("Set up a new address: %d, '%s'(%p)", i, addrs[i], addrs[i]);
+     
+    /* Add it to the command line args */
+    curr+=sprintf(curr,"%s ",addrs[i]);
+  } 
+  addr_len = strlen(addrs[0]);
+
+  /* parse the output and build a new backtrace */
+  e->bt_strings = xbt_new(char*,e->used);
+  
+  VERB1("Fire a first command: '%s'", cmd);
+  pipe = popen(cmd, "r");
+  if (!pipe) {
+    CRITICAL0("Cannot fork addr2line to display the backtrace");
+    abort();
+  }
+
+  for (i=0; i<e->used; i++) {
+    DEBUG2("Looking for symbol %d, addr = '%s'", i, addrs[i]); 
+    fgets(line_func,1024,pipe);
+    line_func[strlen(line_func)-1]='\0';
+    fgets(line_pos,1024,pipe);
+    line_pos[strlen(line_pos)-1]='\0';
+
+    if (strcmp("??",line_func)) {
+      DEBUG2("Found static symbol %s() at %s", line_func, line_pos);
+      e->bt_strings[i] = bprintf("**   In %s() at %s", line_func,line_pos);
+    } else {
+      /* Damn. The symbol is in a dynamic library. Let's get wild */
+      char *maps_name;
+      FILE *maps;
+      char maps_buff[512];
+
+      long int addr,offset=0;
+      char *p,*p2;
+
+      char *subcmd;
+      FILE *subpipe;
+      int found=0;
+
+      /* let's look for the offset of this library in our addressing space */
+      maps_name=bprintf("/proc/%d/maps",(int)getpid());
+      maps=fopen(maps_name,"r");
+
+      sscanf(addrs[i],"%lx",&addr);
+      sprintf(maps_buff,"%#lx",addr);
+      
+      if (strcmp(addrs[i],maps_buff)) {
+       CRITICAL2("Cannot parse backtrace address '%s' (addr=%#lx)",
+                 addrs[i], addr);
+      }
+      DEBUG2("addr=%s (as string) =%#lx (as number)",addrs[i],addr);
+
+      while (!found) {
+       long int first, last;
+       if (fgets(maps_buff,512,maps) == NULL) 
+         break;
+       if (i==0) {
+         maps_buff[strlen(maps_buff) -1]='\0';
+         DEBUG1("map line: %s", maps_buff);
+       }
+       sscanf(maps_buff,"%lx",&first);
+       p=strchr(maps_buff,'-')+1;
+       sscanf(p,"%lx",&last);
+       if (first < addr && addr < last) {
+         offset = first;
+         found=1;
+       }
+       if (found) {          
+          DEBUG3("%#lx in [%#lx-%#lx]", addr, first,last);
+          DEBUG0("Symbol found, map lines not further displayed (even if looking for next ones)");
+       }
+      }
+      fclose(maps);
+      free(maps_name);
+
+      if (!found) {
+       VERB0("Problem while reading the maps file. Following backtrace will be mangled.");
+       DEBUG1("No dynamic. Static symbol: %s", backtrace[i]);
+       e->bt_strings[i] = bprintf("**   In ?? (%s)", backtrace[i]);
+       continue;
+      }
+
+      /* Ok, Found the offset of the maps line containing the searched symbol. 
+        We now need to substract this from the address we got from backtrace.
+      */
+      
+      free(addrs[i]);
+      addrs[i] = bprintf("0x%0*lx",addr_len-2,addr-offset);
+      DEBUG2("offset=%#lx new addr=%s",offset,addrs[i]);
+
+      /* Got it. We have our new address. Let's get the library path and we 
+        are set */ 
+      p  = xbt_strdup(backtrace[i]);
+      if (p[0]=='[') {
+        /* library path not displayed in the map file either... */
+        free(p);
+        sprintf(line_func,"??");
+      } else {
+        p2 = strrchr(p,'(');
+        if (p2) *p2= '\0';
+        p2 = strrchr(p,' ');
+        if(p2) *p2= '\0';
+      
+        /* Here we go, fire an addr2line up */
+        subcmd = bprintf("%s -f -e %s %s",ADDR2LINE,p, addrs[i]);
+        free(p);
+        VERB1("Fire a new command: '%s'",subcmd);
+        subpipe = popen(subcmd,"r");
+        if (!subpipe) {
+           CRITICAL0("Cannot fork addr2line to display the backtrace");
+           abort();
+        }
+        fgets(line_func,1024,subpipe);
+        line_func[strlen(line_func)-1]='\0';
+        fgets(line_pos,1024,subpipe);
+        line_pos[strlen(line_pos)-1]='\0';
+        pclose(subpipe);
+        free(subcmd);
+      }
+
+      /* check whether the trick worked */
+      if (strcmp("??",line_func)) {
+       DEBUG2("Found dynamic symbol %s() at %s", line_func, line_pos);
+       e->bt_strings[i] = bprintf("**   In %s() at %s", line_func,line_pos);
+      } else {
+       /* damn, nothing to do here. Let's print the raw address */
+       DEBUG1("Dynamic symbol not found. Raw address = %s", backtrace[i]);
+       e->bt_strings[i] = bprintf("**   In ?? at %s", backtrace[i]);
+      }
+      
+    }
+    free(addrs[i]);
+     
+    /* Mask the bottom of the stack */    
+    if (!strncmp("main",line_func,strlen("main")) ||
+       !strncmp("xbt_thread_context_wrapper",line_func,strlen("xbt_thread_context_wrapper"))) {
+       int j;
+       for (j=i+1; j<e->used; j++)
+        free(addrs[j]);
+       e->used = i;
+
+       if (!strncmp("xbt_thread_context_wrapper",line_func,strlen("xbt_thread_context_wrapper"))) {
+         e->used++;
+         e->bt_strings[i] = bprintf("**   (in a separate thread)");
+       }       
+    }
+     
+    
+  }
+  pclose(pipe);
+  free(addrs);
+  free(backtrace);
+  free(cmd);
+}
diff --git a/src/xbt/backtrace_windows.c b/src/xbt/backtrace_windows.c
new file mode 100644 (file)
index 0000000..c722966
--- /dev/null
@@ -0,0 +1,439 @@
+/* $Id: ex.c 5173 2008-01-07 22:10:52Z mquinson $ */
+
+/* backtrace_windows - backtrace displaying on windows platform             */
+/* This file is included by ex.c on need (windows x86)                      */
+
+/*  Copyright (c) 2007 The SimGrid team                                     */
+/*  All rights reserved.                                                    */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+/* 
+ * Win32 (x86) implementation backtrace, backtrace_symbols
+ * : support for application self-debugging.
+ */
+
+/* Pointer function to SymInitialize() */
+typedef BOOL (WINAPI *xbt_pfn_sym_initialize_t)(HANDLE, PSTR , BOOL);
+
+/* Pointer function to SymCleanup() */
+typedef BOOL (WINAPI *xbt_pfn_sym_cleanup_t)(HANDLE hProcess);
+
+/* Pointer function to SymFunctionTableAccess() */
+typedef PVOID (WINAPI *xbt_pfn_sym_function_table_access_t)(HANDLE, DWORD);
+
+/* Pointer function to SymGetLineFromAddr() */
+typedef BOOL (WINAPI *xbt_pfn_sym_get_line_from_addr_t)(HANDLE, DWORD, PDWORD , PIMAGEHLP_LINE);
+
+/* Pointer function to SymGetModuleBase() */
+typedef DWORD (WINAPI *xbt_pfn_sym_get_module_base_t)(HANDLE,DWORD);
+
+/* Pointer function to SymGetOptions() */
+typedef DWORD (WINAPI *xbt_pfn_sym_get_options_t)(VOID);
+
+/* Pointer function to SymGetSymFromAddr() */
+typedef BOOL (WINAPI *xbt_pfn_sym_get_sym_from_addr_t)(HANDLE, DWORD, PDWORD , OUT PIMAGEHLP_SYMBOL);
+
+/* Pointer function to SymSetOptions() */
+typedef DWORD (WINAPI *xbt_pfn_sym_set_options_t)(DWORD);
+
+/* Pointer function to StackWalk() */
+typedef BOOL (WINAPI *xbt_pfn_stack_walk_t)(DWORD, HANDLE, HANDLE ,LPSTACKFRAME, PVOID,PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);
+
+/* This structure represents the debug_help library used interface */
+typedef struct s_xbt_debug_help
+{
+       HINSTANCE instance;
+       HANDLE process_handle;                                                                                  
+       xbt_pfn_sym_initialize_t sym_initialize;
+       xbt_pfn_sym_cleanup_t sym_cleanup;
+       xbt_pfn_sym_function_table_access_t sym_function_table_access;
+       xbt_pfn_sym_get_line_from_addr_t sym_get_line_from_addr;
+       xbt_pfn_sym_get_module_base_t sym_get_module_base;
+       xbt_pfn_sym_get_options_t sym_get_options;
+       xbt_pfn_sym_get_sym_from_addr_t sym_get_sym_from_addr;
+       xbt_pfn_sym_set_options_t sym_set_options;
+       xbt_pfn_stack_walk_t stack_walk;
+}s_xbt_debug_hlp_t,* xbt_debug_hlp_t;
+
+
+/* the address to the unique reference to the debug help library interface */
+static xbt_debug_hlp_t 
+dbg_hlp = NULL;
+
+/* initialize the debug help library */
+static int
+dbg_hlp_init(HANDLE process_handle);
+
+/* finalize the debug help library */
+static int
+dbg_hlp_finalize(void);
+
+/*
+ * backtrace() function.
+ *
+ * Returns a backtrace for the calling program, in  the  array
+ * pointed  to  by  buffer.  A backtrace is the series of currently active
+ * function calls for the program.  Each item in the array pointed  to  by
+ * buffer  is  of  type  void *, and is the return address from the corre-
+ * sponding stack frame.  The size argument specifies the  maximum  number
+ * of  addresses that can be stored in buffer.  If the backtrace is larger
+ * than size, then the addresses corresponding to  the  size  most  recent
+ * function  calls  are  returned;  to obtain the complete backtrace, make
+ * sure that buffer and size are large enough.
+ */
+
+int 
+backtrace (void **buffer, int size);
+
+/*
+ * backtrace_symbols() function.
+ *
+ * Given the set of addresses returned by  backtrace()  in  buffer,  back-
+ * trace_symbols()  translates the addresses into an array of strings containing
+ * the name, the source file and the line number or the las called functions.
+ */
+char ** 
+backtrace_symbols (void *const *buffer, int size);
+
+#endif
+
+void xbt_ex_setup_backtrace(xbt_ex_t *e)  {
+int i;
+char **backtrace = backtrace_symbols (e->bt, e->used);
+  
+  /* parse the output and build a new backtrace */
+  e->bt_strings = xbt_new(char*,e->used);
+  
+
+  for(i=0; i<e->used; i++) 
+  {
+      e->bt_strings[i] = xbt_strdup(backtrace[i]);
+      free(backtrace[i]);
+  }
+  
+  free(backtrace);
+}    
+
+int 
+backtrace (void **buffer, int size)
+{
+       int pos = 0;
+       STACKFRAME* stack_frame;
+       int first = 1;
+
+       IMAGEHLP_SYMBOL * pSym;
+       unsigned long offset = 0;
+       IMAGEHLP_LINE line_info = {0};
+       byte __buffer[(sizeof(SYMBOL_INFO) +MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
+
+       CONTEXT context = {CONTEXT_FULL};
+       GetThreadContext(GetCurrentThread(), &context);
+       
+       /* ebp points on stack base */
+       /* esp points on stack pointer, ie on last stacked element (current element) */
+       _asm call $+5
+       _asm pop eax 
+       _asm mov context.Eip, eax 
+       _asm mov eax, esp 
+       _asm mov context.Esp, eax 
+       _asm mov context.Ebp, ebp 
+
+       dbg_hlp_init(GetCurrentProcess());
+       
+       if((NULL == dbg_hlp) || (size <= 0) || (NULL == buffer))
+       {
+               errno = EINVAL;
+               return 0;
+       }
+
+       for(pos = 0; pos < size; pos++)
+               buffer[pos] = NULL;
+       
+       pos = 0;
+
+       pSym = (IMAGEHLP_SYMBOL*)__buffer;
+
+       pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
+       pSym->MaxNameLength = MAX_SYM_NAME;
+
+
+       line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE);
+       
+
+    while(pos < size)
+    {
+               stack_frame = (void*)calloc(1,sizeof(STACKFRAME));
+               
+               if(!stack_frame)
+               {
+                       errno = ENOMEM;
+                       break;
+               }
+               
+               stack_frame->AddrPC.Offset = context.Eip;
+           stack_frame->AddrPC.Mode = AddrModeFlat;
+       
+           stack_frame->AddrFrame.Offset = context.Ebp;
+           stack_frame->AddrFrame.Mode = AddrModeFlat;
+       
+           stack_frame->AddrStack.Offset = context.Esp;
+           stack_frame->AddrStack.Mode = AddrModeFlat;
+               
+               if((*(dbg_hlp->stack_walk))(
+                                       IMAGE_FILE_MACHINE_I386,
+                                       dbg_hlp->process_handle,
+                                       GetCurrentThread(),
+                                       stack_frame, 
+                                       &context,
+                                       NULL,
+                                       dbg_hlp->sym_function_table_access,
+                                       dbg_hlp->sym_get_module_base,
+                                       NULL)
+                       && !first) 
+               {
+                       if(stack_frame->AddrReturn.Offset)
+                       {
+
+                               if((*(dbg_hlp->sym_get_sym_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,pSym))
+                               {       
+                                       if((*(dbg_hlp->sym_get_line_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,&line_info))
+                                               buffer[pos++] = (void*)stack_frame;
+                               }
+                       }
+                       else
+                       {
+                               free(stack_frame); /* no symbol or no line info */
+                               break;
+                       }
+               }
+               else
+               {
+                       free(stack_frame);
+
+                       if(first)
+                               first = 0;
+                       else
+                               break;
+               }               
+    }
+
+    return pos;
+}
+
+char ** 
+backtrace_symbols (void *const *buffer, int size)
+{
+       int pos;
+       int success = 0;        
+       char** strings;
+       STACKFRAME* stack_frame;
+       IMAGEHLP_SYMBOL * pSym;
+       unsigned long offset = 0;
+       IMAGEHLP_LINE line_info = {0};
+       IMAGEHLP_MODULE module = {0};
+       byte __buffer[(sizeof(SYMBOL_INFO) +MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
+
+       if((NULL == dbg_hlp) || (size <= 0) || (NULL == buffer))
+       {
+               errno = EINVAL;
+               return NULL;
+       }
+       
+       strings = (char**)calloc(size,sizeof(char*));
+       
+       if(NULL == strings)
+       {
+               errno = ENOMEM;
+               return NULL;
+       }
+       
+       pSym = (IMAGEHLP_SYMBOL*)__buffer;
+
+       pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
+       pSym->MaxNameLength = MAX_SYM_NAME;
+
+
+       line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE);
+       module.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
+       
+       for(pos = 0; pos < size; pos++)
+       {
+               stack_frame = (STACKFRAME*)(buffer[pos]);
+
+               if(NULL != stack_frame)
+               {
+               
+                       if((*(dbg_hlp->sym_get_sym_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,pSym))
+                       {       
+                               if((*(dbg_hlp->sym_get_line_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,&line_info))
+                               {
+                                       strings[pos] = bprintf("**   In %s() at %s:%d", pSym->Name,line_info.FileName,line_info.LineNumber);
+                               }
+                               else
+                               {
+                                       strings[pos] = bprintf("**   In %s()", pSym->Name);
+                               }
+                               success = 1;
+                       }
+                       else
+                       {
+                               strings[pos] = xbt_strdup("**   <no symbol>");
+                       }
+
+                       free(stack_frame);
+               }
+               else
+                       break;
+       }
+       
+       if(!success)
+       {
+               free(strings);
+               strings = NULL;
+       }
+
+       dbg_hlp_finalize();
+       
+       return strings;
+}
+
+static int
+dbg_hlp_init(HANDLE process_handle)
+{
+       if(dbg_hlp)
+       {
+               /* debug help is already loaded */
+               return 0;
+       }
+
+       /* allocation */
+       dbg_hlp = (xbt_debug_hlp_t)calloc(1,sizeof(s_xbt_debug_hlp_t));
+       
+       if(!dbg_hlp)
+               return ENOMEM;
+       
+       /* load the library */
+       dbg_hlp->instance = LoadLibraryA("Dbghelp.dll");
+       
+       if(!(dbg_hlp->instance))
+       {
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();
+       }
+       
+       /* get the pointers to debug help library exported functions */
+       
+       if(!((dbg_hlp->sym_initialize) = (xbt_pfn_sym_initialize_t)GetProcAddress(dbg_hlp->instance,"SymInitialize")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+               
+       if(!((dbg_hlp->sym_cleanup) = (xbt_pfn_sym_cleanup_t)GetProcAddress(dbg_hlp->instance,"SymCleanup")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_function_table_access) = (xbt_pfn_sym_function_table_access_t)GetProcAddress(dbg_hlp->instance,"SymFunctionTableAccess")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_get_line_from_addr) = (xbt_pfn_sym_get_line_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetLineFromAddr")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_get_module_base) = (xbt_pfn_sym_get_module_base_t)GetProcAddress(dbg_hlp->instance,"SymGetModuleBase")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_get_options) = (xbt_pfn_sym_get_options_t)GetProcAddress(dbg_hlp->instance,"SymGetOptions")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_get_sym_from_addr) = (xbt_pfn_sym_get_sym_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetSymFromAddr")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->sym_set_options) = (xbt_pfn_sym_set_options_t)GetProcAddress(dbg_hlp->instance,"SymSetOptions")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       if(!((dbg_hlp->stack_walk) = (xbt_pfn_stack_walk_t)GetProcAddress(dbg_hlp->instance,"StackWalk")))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();     
+       }
+       
+       dbg_hlp->process_handle = process_handle;
+
+       (*(dbg_hlp->sym_set_options))((*(dbg_hlp->sym_get_options))() | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
+       
+       if(!(*(dbg_hlp->sym_initialize))(dbg_hlp->process_handle,0,1))
+       {
+               FreeLibrary(dbg_hlp->instance);
+               free(dbg_hlp);
+               dbg_hlp = NULL;
+               return (int)GetLastError();
+       }
+               
+       
+       return 0;
+}
+
+static int
+dbg_hlp_finalize(void)
+{
+       if(!dbg_hlp)
+               return EINVAL;
+               
+       if(!(*(dbg_hlp->sym_cleanup))(dbg_hlp->process_handle))
+               return (int)GetLastError();
+       
+       if(!FreeLibrary(dbg_hlp->instance))
+               return (int)GetLastError();
+       
+       free(dbg_hlp);
+       dbg_hlp = NULL;
+       
+       return 0;
+}
+
+/* dummy implementation. We won't use the result, but ex.h needs it to be defined */
+int backtrace (void **__array, int __size) {
+  return 0;    
+}
+
index f9e62b1..091a4cd 100644 (file)
 #include "gras/Virtu/virtu_interface.h" /* gras_os_myname */
 #include "xbt/ex_interface.h"
 
 #include "gras/Virtu/virtu_interface.h" /* gras_os_myname */
 #include "xbt/ex_interface.h"
 
-#if (defined(WIN32) && defined(_M_IX86))
-#include <dbghelp.h>
+#undef HAVE_BACKTRACE
+#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) 
+# define HAVE_BACKTRACE 1 /* Hello linux box */
 #endif
 
 #endif
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex,xbt,"Exception mecanism");
-
-#if (defined(WIN32) && defined(_M_IX86))
-
-/* 
- * Win32 (x86) implementation backtrace, backtrace_symbols
- * : support for application self-debugging.
- */
-
-/* Pointer function to SymInitialize() */
-typedef BOOL (WINAPI *xbt_pfn_sym_initialize_t)(HANDLE, PSTR , BOOL);
-
-/* Pointer function to SymCleanup() */
-typedef BOOL (WINAPI *xbt_pfn_sym_cleanup_t)(HANDLE hProcess);
-
-/* Pointer function to SymFunctionTableAccess() */
-typedef PVOID (WINAPI *xbt_pfn_sym_function_table_access_t)(HANDLE, DWORD);
-
-/* Pointer function to SymGetLineFromAddr() */
-typedef BOOL (WINAPI *xbt_pfn_sym_get_line_from_addr_t)(HANDLE, DWORD, PDWORD , PIMAGEHLP_LINE);
-
-/* Pointer function to SymGetModuleBase() */
-typedef DWORD (WINAPI *xbt_pfn_sym_get_module_base_t)(HANDLE,DWORD);
-
-/* Pointer function to SymGetOptions() */
-typedef DWORD (WINAPI *xbt_pfn_sym_get_options_t)(VOID);
-
-/* Pointer function to SymGetSymFromAddr() */
-typedef BOOL (WINAPI *xbt_pfn_sym_get_sym_from_addr_t)(HANDLE, DWORD, PDWORD , OUT PIMAGEHLP_SYMBOL);
-
-/* Pointer function to SymSetOptions() */
-typedef DWORD (WINAPI *xbt_pfn_sym_set_options_t)(DWORD);
-
-/* Pointer function to StackWalk() */
-typedef BOOL (WINAPI *xbt_pfn_stack_walk_t)(DWORD, HANDLE, HANDLE ,LPSTACKFRAME, PVOID,PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);
-
-/* This structure representes the debug_help library used interface */
-typedef struct s_xbt_debug_help
-{
-       HINSTANCE instance;
-       HANDLE process_handle;                                                                                  
-       xbt_pfn_sym_initialize_t sym_initialize;
-       xbt_pfn_sym_cleanup_t sym_cleanup;
-       xbt_pfn_sym_function_table_access_t sym_function_table_access;
-       xbt_pfn_sym_get_line_from_addr_t sym_get_line_from_addr;
-       xbt_pfn_sym_get_module_base_t sym_get_module_base;
-       xbt_pfn_sym_get_options_t sym_get_options;
-       xbt_pfn_sym_get_sym_from_addr_t sym_get_sym_from_addr;
-       xbt_pfn_sym_set_options_t sym_set_options;
-       xbt_pfn_stack_walk_t stack_walk;
-}s_xbt_debug_hlp_t,* xbt_debug_hlp_t;
-
-
-/* the address to the unique reference to the debug help library interface */
-static xbt_debug_hlp_t 
-dbg_hlp = NULL;
-
-/* initialize the debug help library */
-static int
-dbg_hlp_init(HANDLE process_handle);
-
-/* finalize the debug help library */
-static int
-dbg_hlp_finalize(void);
-
-/*
- * backtrace() function.
- *
- * Returns a backtrace for the calling program, in  the  array
- * pointed  to  by  buffer.  A backtrace is the series of currently active
- * function calls for the program.  Each item in the array pointed  to  by
- * buffer  is  of  type  void *, and is the return address from the corre-
- * sponding stack frame.  The size argument specifies the  maximum  number
- * of  addresses that can be stored in buffer.  If the backtrace is larger
- * than size, then the addresses corresponding to  the  size  most  recent
- * function  calls  are  returned;  to obtain the complete backtrace, make
- * sure that buffer and size are large enough.
- */
-
-int 
-backtrace (void **buffer, int size);
-
-/*
- * backtrace_symbols() function.
- *
- * Given the set of addresses returned by  backtrace()  in  buffer,  back-
- * trace_symbols()  translates the addresses into an array of strings containing
- * the name, the source file and the line number or the las called functions.
- */
-char ** 
-backtrace_symbols (void *const *buffer, int size);
+#if defined(WIN32) && defined(_M_IX86)
+# define HAVE_BACKTRACE 1 /* Hello x86 windows box */
+#endif 
+   
 
 
-#endif
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex,xbt,"Exception mecanism");
 
 /* default __ex_ctx callback function */
 ex_ctx_t *__xbt_ex_ctx_default(void) {
 
 /* default __ex_ctx callback function */
 ex_ctx_t *__xbt_ex_ctx_default(void) {
@@ -142,7 +56,7 @@ ex_ctx_t *__xbt_ex_ctx_default(void) {
 void xbt_ex_setup_backtrace(xbt_ex_t *e);
 
 void xbt_backtrace_current(xbt_ex_t *e) {
 void xbt_ex_setup_backtrace(xbt_ex_t *e);
 
 void xbt_backtrace_current(xbt_ex_t *e) {
-#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) || (defined(WIN32) && defined(_M_IX86))
+#ifdef HAVE_BACKTRACE
   e->used     = backtrace((void**)e->bt,XBT_BACKTRACE_SIZE);
   e->bt_strings = NULL;
   xbt_ex_setup_backtrace(e);
   e->used     = backtrace((void**)e->bt,XBT_BACKTRACE_SIZE);
   e->bt_strings = NULL;
   xbt_ex_setup_backtrace(e);
@@ -150,7 +64,7 @@ void xbt_backtrace_current(xbt_ex_t *e) {
 }
 
 void xbt_backtrace_display(xbt_ex_t *e) {
 }
 
 void xbt_backtrace_display(xbt_ex_t *e) {
-#if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE) || (defined(WIN32) && defined(_M_IX86))
+#ifdef HAVE_BACKTRACE
   int i;
 
   if (e->used == 0) {
   int i;
 
   if (e->used == 0) {
@@ -179,258 +93,14 @@ void xbt_backtrace_display_current(void) {
   xbt_backtrace_display(&e);
 }
 
   xbt_backtrace_display(&e);
 }
 
-#ifndef WIN32
-extern char **environ; /* the environment, as specified by the opengroup */
-#endif
-
-void xbt_ex_setup_backtrace(xbt_ex_t *e)  {
 #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
 #if defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)
-  int i;
-  /* to get the backtrace from the libc */
-  char **backtrace = backtrace_symbols (e->bt, e->used);
-  
-  /* To build the commandline of addr2line */
-  char *cmd, *curr;
-  
-  /* to extract the addresses from the backtrace */
-  char **addrs=xbt_new(char*,e->used);
-  char buff[256],*p;
-  
-  /* To read the output of addr2line */
-  FILE *pipe;
-  char line_func[1024],line_pos[1024];
-
-  /* size (in char) of pointers on this arch */
-  int addr_len=0;
-
-  /* To search for the right executable path when not trivial */
-  struct stat stat_buf;
-  char *binary_name = NULL;
-   
-  /* Some arches only have stubs of backtrace, no implementation (hppa comes to mind) */
-  if (!e->used)
-     return;
-   
-  /* build the commandline */
-  if (stat(xbt_binary_name,&stat_buf)) {
-    /* Damn. binary not in current dir. We'll have to dig the PATH to find it */
-    int i;
-    for (i=0; environ[i]; i++) {
-      if (!strncmp("PATH=",environ[i], 5)) {   
-       xbt_dynar_t path=xbt_str_split(environ[i] + 5, ":");
-       unsigned int cpt;
-       char *data;
-       xbt_dynar_foreach(path, cpt, data) {
-         if (binary_name)
-           free(binary_name);
-         binary_name = bprintf("%s/%s",data,xbt_binary_name);
-         if (!stat(binary_name,&stat_buf)) {
-           /* Found. */
-           DEBUG1("Looked in the PATH for the binary. Found %s",binary_name);
-           xbt_dynar_free(&path);
-           break;
-         } 
-       }
-       if (stat(binary_name,&stat_buf)) {
-         /* not found */
-         e->used = 1;
-         e->bt_strings = xbt_new(char*,1);
-         e->bt_strings[0] = bprintf("(binary '%s' not found the path)",xbt_binary_name);
-         return;
-       }
-       xbt_dynar_free(&path);
-       break;
-      }        
-    }
-  } else {
-    binary_name = xbt_strdup(xbt_binary_name);
-  }      
-  cmd = curr = xbt_new(char,strlen(ADDR2LINE)+25+strlen(binary_name)+32*e->used);
-   
-  curr += sprintf(curr,"%s -f -e %s ",ADDR2LINE,binary_name);
-  free(binary_name);
-   
-  for (i=0; i<e->used;i++) {
-    /* retrieve this address */
-    DEBUG2("Retrieving address number %d from '%s'", i, backtrace[i]);
-    snprintf(buff,256,"%s",strchr(backtrace[i],'[')+1);
-    p=strchr(buff,']');
-    *p='\0';
-    if (strcmp(buff,"(nil)"))
-       addrs[i]=bprintf("%s", buff);
-    else
-       addrs[i]=bprintf("0x0");
-    DEBUG3("Set up a new address: %d, '%s'(%p)", i, addrs[i], addrs[i]);
-     
-    /* Add it to the command line args */
-    curr+=sprintf(curr,"%s ",addrs[i]);
-  } 
-  addr_len = strlen(addrs[0]);
-
-  /* parse the output and build a new backtrace */
-  e->bt_strings = xbt_new(char*,e->used);
-  
-  VERB1("Fire a first command: '%s'", cmd);
-  pipe = popen(cmd, "r");
-  if (!pipe) {
-    CRITICAL0("Cannot fork addr2line to display the backtrace");
-    abort();
-  }
-
-  for (i=0; i<e->used; i++) {
-    DEBUG2("Looking for symbol %d, addr = '%s'", i, addrs[i]); 
-    fgets(line_func,1024,pipe);
-    line_func[strlen(line_func)-1]='\0';
-    fgets(line_pos,1024,pipe);
-    line_pos[strlen(line_pos)-1]='\0';
-
-    if (strcmp("??",line_func)) {
-      DEBUG2("Found static symbol %s() at %s", line_func, line_pos);
-      e->bt_strings[i] = bprintf("**   In %s() at %s", line_func,line_pos);
-    } else {
-      /* Damn. The symbol is in a dynamic library. Let's get wild */
-      char *maps_name;
-      FILE *maps;
-      char maps_buff[512];
-
-      long int addr,offset=0;
-      char *p,*p2;
-
-      char *subcmd;
-      FILE *subpipe;
-      int found=0;
-
-      /* let's look for the offset of this library in our addressing space */
-      maps_name=bprintf("/proc/%d/maps",(int)getpid());
-      maps=fopen(maps_name,"r");
-
-      sscanf(addrs[i],"%lx",&addr);
-      sprintf(maps_buff,"%#lx",addr);
-      
-      if (strcmp(addrs[i],maps_buff)) {
-       CRITICAL2("Cannot parse backtrace address '%s' (addr=%#lx)",
-                 addrs[i], addr);
-      }
-      DEBUG2("addr=%s (as string) =%#lx (as number)",addrs[i],addr);
-
-      while (!found) {
-       long int first, last;
-       if (fgets(maps_buff,512,maps) == NULL) 
-         break;
-       if (i==0) {
-         maps_buff[strlen(maps_buff) -1]='\0';
-         DEBUG1("map line: %s", maps_buff);
-       }
-       sscanf(maps_buff,"%lx",&first);
-       p=strchr(maps_buff,'-')+1;
-       sscanf(p,"%lx",&last);
-       if (first < addr && addr < last) {
-         offset = first;
-         found=1;
-       }
-       if (found) {          
-          DEBUG3("%#lx in [%#lx-%#lx]", addr, first,last);
-          DEBUG0("Symbol found, map lines not further displayed (even if looking for next ones)");
-       }
-      }
-      fclose(maps);
-      free(maps_name);
-
-      if (!found) {
-       VERB0("Problem while reading the maps file. Following backtrace will be mangled.");
-       DEBUG1("No dynamic. Static symbol: %s", backtrace[i]);
-       e->bt_strings[i] = bprintf("**   In ?? (%s)", backtrace[i]);
-       continue;
-      }
-
-      /* Ok, Found the offset of the maps line containing the searched symbol. 
-        We now need to substract this from the address we got from backtrace.
-      */
-      
-      free(addrs[i]);
-      addrs[i] = bprintf("0x%0*lx",addr_len-2,addr-offset);
-      DEBUG2("offset=%#lx new addr=%s",offset,addrs[i]);
-
-      /* Got it. We have our new address. Let's get the library path and we 
-        are set */ 
-      p  = xbt_strdup(backtrace[i]);
-      if (p[0]=='[') {
-        /* library path not displayed in the map file either... */
-        free(p);
-        sprintf(line_func,"??");
-      } else {
-        p2 = strrchr(p,'(');
-        if (p2) *p2= '\0';
-        p2 = strrchr(p,' ');
-        if(p2) *p2= '\0';
-      
-        /* Here we go, fire an addr2line up */
-        subcmd = bprintf("%s -f -e %s %s",ADDR2LINE,p, addrs[i]);
-        free(p);
-        VERB1("Fire a new command: '%s'",subcmd);
-        subpipe = popen(subcmd,"r");
-        if (!subpipe) {
-           CRITICAL0("Cannot fork addr2line to display the backtrace");
-           abort();
-        }
-        fgets(line_func,1024,subpipe);
-        line_func[strlen(line_func)-1]='\0';
-        fgets(line_pos,1024,subpipe);
-        line_pos[strlen(line_pos)-1]='\0';
-        pclose(subpipe);
-        free(subcmd);
-      }
-
-      /* check whether the trick worked */
-      if (strcmp("??",line_func)) {
-       DEBUG2("Found dynamic symbol %s() at %s", line_func, line_pos);
-       e->bt_strings[i] = bprintf("**   In %s() at %s", line_func,line_pos);
-      } else {
-       /* damn, nothing to do here. Let's print the raw address */
-       DEBUG1("Dynamic symbol not found. Raw address = %s", backtrace[i]);
-       e->bt_strings[i] = bprintf("**   In ?? at %s", backtrace[i]);
-      }
-      
-    }
-    free(addrs[i]);
-     
-    /* Mask the bottom of the stack */    
-    if (!strncmp("main",line_func,strlen("main")) ||
-       !strncmp("xbt_thread_context_wrapper",line_func,strlen("xbt_thread_context_wrapper"))) {
-       int j;
-       for (j=i+1; j<e->used; j++)
-        free(addrs[j]);
-       e->used = i;
-
-       if (!strncmp("xbt_thread_context_wrapper",line_func,strlen("xbt_thread_context_wrapper"))) {
-         e->used++;
-         e->bt_strings[i] = bprintf("**   (in a separate thread)");
-       }       
-    }
-     
-    
-  }
-  pclose(pipe);
-  free(addrs);
-  free(backtrace);
-  free(cmd);
+# include "backtrace_linux.c"
 #elif (defined(WIN32) && defined (_M_IX86))
 #elif (defined(WIN32) && defined (_M_IX86))
-int i;
-char **backtrace = backtrace_symbols (e->bt, e->used);
-  
-  /* parse the output and build a new backtrace */
-  e->bt_strings = xbt_new(char*,e->used);
-  
-
-  for(i=0; i<e->used; i++) 
-  {
-      e->bt_strings[i] = xbt_strdup(backtrace[i]);
-      free(backtrace[i]);
-  }
-  
-  free(backtrace);
+# include "backtrace_windows.c"
+#else
+void xbt_ex_setup_backtrace(xbt_ex_t *e)  {
+}
 #endif
 #endif
-}    
 
 /** @brief shows an exception content and the associated stack if available */
 void xbt_ex_display(xbt_ex_t *e)  {
 
 /** @brief shows an exception content and the associated stack if available */
 void xbt_ex_display(xbt_ex_t *e)  {
@@ -454,7 +124,7 @@ void xbt_ex_display(xbt_ex_t *e)  {
   if (!e->remote && !e->bt_strings)
     xbt_ex_setup_backtrace(e);
 
   if (!e->remote && !e->bt_strings)
     xbt_ex_setup_backtrace(e);
 
-#if (defined(HAVE_EXECINFO_H) && defined(HAVE_POPEN) && defined(ADDR2LINE)) || (defined(WIN32) && defined(_M_IX86))
+#ifdef HAVE_BACKTRACE
   /* We have everything to build neat backtraces */
   {
     int i;
   /* We have everything to build neat backtraces */
   {
     int i;
@@ -518,331 +188,6 @@ const char * xbt_ex_catname(xbt_errcat_t cat) {
   }
 }
 
   }
 }
 
-#ifndef HAVE_EXECINFO_H
-#  if (defined(WIN32) && defined(_M_IX86))
-int 
-backtrace (void **buffer, int size)
-{
-       int pos = 0;
-       STACKFRAME* stack_frame;
-       int first = 1;
-
-       IMAGEHLP_SYMBOL * pSym;
-       unsigned long offset = 0;
-       IMAGEHLP_LINE line_info = {0};
-       byte __buffer[(sizeof(SYMBOL_INFO) +MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
-
-       CONTEXT context = {CONTEXT_FULL};
-       GetThreadContext(GetCurrentThread(), &context);
-       
-       /* ebp points on stack base */
-       /* esp points on stack pointer, ie on last stacked element (current element) */
-       _asm call $+5
-       _asm pop eax 
-       _asm mov context.Eip, eax 
-       _asm mov eax, esp 
-       _asm mov context.Esp, eax 
-       _asm mov context.Ebp, ebp 
-
-       dbg_hlp_init(GetCurrentProcess());
-       
-       if((NULL == dbg_hlp) || (size <= 0) || (NULL == buffer))
-       {
-               errno = EINVAL;
-               return 0;
-       }
-
-       for(pos = 0; pos < size; pos++)
-               buffer[pos] = NULL;
-       
-       pos = 0;
-
-       pSym = (IMAGEHLP_SYMBOL*)__buffer;
-
-       pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
-       pSym->MaxNameLength = MAX_SYM_NAME;
-
-
-       line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE);
-       
-
-    while(pos < size)
-    {
-               stack_frame = (void*)calloc(1,sizeof(STACKFRAME));
-               
-               if(!stack_frame)
-               {
-                       errno = ENOMEM;
-                       break;
-               }
-               
-               stack_frame->AddrPC.Offset = context.Eip;
-           stack_frame->AddrPC.Mode = AddrModeFlat;
-       
-           stack_frame->AddrFrame.Offset = context.Ebp;
-           stack_frame->AddrFrame.Mode = AddrModeFlat;
-       
-           stack_frame->AddrStack.Offset = context.Esp;
-           stack_frame->AddrStack.Mode = AddrModeFlat;
-               
-               if((*(dbg_hlp->stack_walk))(
-                                       IMAGE_FILE_MACHINE_I386,
-                                       dbg_hlp->process_handle,
-                                       GetCurrentThread(),
-                                       stack_frame, 
-                                       &context,
-                                       NULL,
-                                       dbg_hlp->sym_function_table_access,
-                                       dbg_hlp->sym_get_module_base,
-                                       NULL)
-                       && !first) 
-               {
-                       if(stack_frame->AddrReturn.Offset)
-                       {
-
-                               if((*(dbg_hlp->sym_get_sym_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,pSym))
-                               {       
-                                       if((*(dbg_hlp->sym_get_line_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,&line_info))
-                                               buffer[pos++] = (void*)stack_frame;
-                               }
-                       }
-                       else
-                       {
-                               free(stack_frame); /* no symbol or no line info */
-                               break;
-                       }
-               }
-               else
-               {
-                       free(stack_frame);
-
-                       if(first)
-                               first = 0;
-                       else
-                               break;
-               }               
-    }
-
-    return pos;
-}
-
-char ** 
-backtrace_symbols (void *const *buffer, int size)
-{
-       int pos;
-       int success = 0;        
-       char** strings;
-       STACKFRAME* stack_frame;
-       IMAGEHLP_SYMBOL * pSym;
-       unsigned long offset = 0;
-       IMAGEHLP_LINE line_info = {0};
-       IMAGEHLP_MODULE module = {0};
-       byte __buffer[(sizeof(SYMBOL_INFO) +MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
-
-       if((NULL == dbg_hlp) || (size <= 0) || (NULL == buffer))
-       {
-               errno = EINVAL;
-               return NULL;
-       }
-       
-       strings = (char**)calloc(size,sizeof(char*));
-       
-       if(NULL == strings)
-       {
-               errno = ENOMEM;
-               return NULL;
-       }
-       
-       pSym = (IMAGEHLP_SYMBOL*)__buffer;
-
-       pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
-       pSym->MaxNameLength = MAX_SYM_NAME;
-
-
-       line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE);
-       module.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
-       
-       for(pos = 0; pos < size; pos++)
-       {
-               stack_frame = (STACKFRAME*)(buffer[pos]);
-
-               if(NULL != stack_frame)
-               {
-               
-                       if((*(dbg_hlp->sym_get_sym_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,pSym))
-                       {       
-                               if((*(dbg_hlp->sym_get_line_from_addr))(dbg_hlp->process_handle,stack_frame->AddrPC.Offset, &offset,&line_info))
-                               {
-                                       strings[pos] = bprintf("**   In %s() at %s:%d", pSym->Name,line_info.FileName,line_info.LineNumber);
-                               }
-                               else
-                               {
-                                       strings[pos] = bprintf("**   In %s()", pSym->Name);
-                               }
-                               success = 1;
-                       }
-                       else
-                       {
-                               strings[pos] = xbt_strdup("**   <no symbol>");
-                       }
-
-                       free(stack_frame);
-               }
-               else
-                       break;
-       }
-       
-       if(!success)
-       {
-               free(strings);
-               strings = NULL;
-       }
-
-       dbg_hlp_finalize();
-       
-       return strings;
-}
-
-static int
-dbg_hlp_init(HANDLE process_handle)
-{
-       if(dbg_hlp)
-       {
-               /* debug help is already loaded */
-               return 0;
-       }
-
-       /* allocation */
-       dbg_hlp = (xbt_debug_hlp_t)calloc(1,sizeof(s_xbt_debug_hlp_t));
-       
-       if(!dbg_hlp)
-               return ENOMEM;
-       
-       /* load the library */
-       dbg_hlp->instance = LoadLibraryA("Dbghelp.dll");
-       
-       if(!(dbg_hlp->instance))
-       {
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();
-       }
-       
-       /* get the pointers to debug help library exported functions */
-       
-       if(!((dbg_hlp->sym_initialize) = (xbt_pfn_sym_initialize_t)GetProcAddress(dbg_hlp->instance,"SymInitialize")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-               
-       if(!((dbg_hlp->sym_cleanup) = (xbt_pfn_sym_cleanup_t)GetProcAddress(dbg_hlp->instance,"SymCleanup")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_function_table_access) = (xbt_pfn_sym_function_table_access_t)GetProcAddress(dbg_hlp->instance,"SymFunctionTableAccess")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_get_line_from_addr) = (xbt_pfn_sym_get_line_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetLineFromAddr")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_get_module_base) = (xbt_pfn_sym_get_module_base_t)GetProcAddress(dbg_hlp->instance,"SymGetModuleBase")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_get_options) = (xbt_pfn_sym_get_options_t)GetProcAddress(dbg_hlp->instance,"SymGetOptions")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_get_sym_from_addr) = (xbt_pfn_sym_get_sym_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetSymFromAddr")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->sym_set_options) = (xbt_pfn_sym_set_options_t)GetProcAddress(dbg_hlp->instance,"SymSetOptions")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       if(!((dbg_hlp->stack_walk) = (xbt_pfn_stack_walk_t)GetProcAddress(dbg_hlp->instance,"StackWalk")))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();     
-       }
-       
-       dbg_hlp->process_handle = process_handle;
-
-       (*(dbg_hlp->sym_set_options))((*(dbg_hlp->sym_get_options))() | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
-       
-       if(!(*(dbg_hlp->sym_initialize))(dbg_hlp->process_handle,0,1))
-       {
-               FreeLibrary(dbg_hlp->instance);
-               free(dbg_hlp);
-               dbg_hlp = NULL;
-               return (int)GetLastError();
-       }
-               
-       
-       return 0;
-}
-
-static int
-dbg_hlp_finalize(void)
-{
-       if(!dbg_hlp)
-               return EINVAL;
-               
-       if(!(*(dbg_hlp->sym_cleanup))(dbg_hlp->process_handle))
-               return (int)GetLastError();
-       
-       if(!FreeLibrary(dbg_hlp->instance))
-               return (int)GetLastError();
-       
-       free(dbg_hlp);
-       dbg_hlp = NULL;
-       
-       return 0;
-}
-#  endif
-#else
-/* dummy implementation. We won't use the result, but ex.h needs it to be defined */
-int backtrace (void **__array, int __size) {
-  return 0;    
-}
-
-#endif
 
 #ifdef SIMGRID_TEST
 #include <stdio.h>
 
 #ifdef SIMGRID_TEST
 #include <stdio.h>