Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move the backtrace code out of the exception code
authorGabriel Corona <gabriel.corona@loria.fr>
Fri, 10 Jun 2016 10:14:46 +0000 (12:14 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Fri, 10 Jun 2016 11:14:20 +0000 (13:14 +0200)
13 files changed:
include/xbt/backtrace.h [new file with mode: 0644]
include/xbt/ex.h
include/xbt/misc.h
src/bindings/java/JavaContext.cpp
src/xbt/backtrace.cpp [new file with mode: 0644]
src/xbt/backtrace_dummy.cpp [moved from src/xbt/backtrace_dummy.c with 73% similarity]
src/xbt/backtrace_linux.cpp [moved from src/xbt/backtrace_linux.c with 65% similarity]
src/xbt/ex.cpp
src/xbt/ex_interface.h
src/xbt/log.c
src/xbt/xbt_log_layout_format.c
src/xbt/xbt_os_thread.c
tools/cmake/DefinePackages.cmake

diff --git a/include/xbt/backtrace.h b/include/xbt/backtrace.h
new file mode 100644 (file)
index 0000000..bb2a905
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright (c) 2005-2019. 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/>           */
+/*  All rights reserved.                                                    */
+
+/* This code is inspirated from the OSSP version (as retrieved back in 2004)*/
+/* It was heavily modified to fit the SimGrid framework.                    */
+
+/* The OSSP version has the following copyright notice:
+**  OSSP ex - Exception Handling
+**  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/>
+**
+**  This file is part of OSSP ex, an exception handling library
+**  which can be found at http://www.ossp.org/pkg/lib/ex/.
+**
+**  Permission to use, copy, modify, and distribute this software for
+**  any purpose with or without fee is hereby granted, provided that
+**  the above copyright notice and this permission notice appear in all
+**  copies.
+**
+**  THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESSED OR IMPLIED
+**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+**  SUCH DAMAGE.
+ */
+
+/* The extensions made for the SimGrid project can either be distributed    */
+/* under the same license, or under the LGPL v2.1                           */
+
+#ifndef SIMGRIX_XBT_BACKTRACE_H
+#define SIMGRIX_XBT_BACKTRACE_H
+
+#include <cstddef>
+
+#include <xbt/base.h>
+
+SG_BEGIN_DECL()
+
+typedef void* xbt_backtrace_location_t;
+
+/** @brief Shows a backtrace of the current location */
+XBT_PUBLIC(void) xbt_backtrace_display_current(void);
+
+/** @brief reimplementation of glibc backtrace based directly on gcc library, without implicit malloc  */
+XBT_PUBLIC(int) xbt_backtrace_no_malloc(void**bt, int size);
+
+/** @brief Captures a backtrace for further use */
+XBT_PUBLIC(size_t) xbt_backtrace_current(xbt_backtrace_location_t* loc, size_t count);
+
+/** @brief Display a previously captured backtrace */
+XBT_PUBLIC(void) xbt_backtrace_display(xbt_backtrace_location_t* loc, size_t count);
+
+/** @brief Get current backtrace with libunwind */
+XBT_PUBLIC(int) xbt_libunwind_backtrace(void** bt, int size);
+
+SG_END_DECL()
+
+#endif
index a7ec2f8..6a4e505 100644 (file)
@@ -1,5 +1,3 @@
-/* ex - Exception Handling                                                  */
-
 /* Copyright (c) 2005-2015. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* Copyright (c) 2005-2015. The SimGrid Team.
  * All rights reserved.                                                     */
 
@@ -115,9 +113,7 @@ public:
   const char *file;             /**< Thrown point */
   int line;                     /**< Thrown point */
   const char *func;             /**< Thrown point */
   const char *file;             /**< Thrown point */
   int line;                     /**< Thrown point */
   const char *func;             /**< Thrown point */
-  /* Backtrace */
-  std::vector<std::string>      bt_strings;
-  std::vector<void*>            bt;
+  std::vector<void*>            bt; /**< Backtrace */
 };
 #endif
 
 };
 #endif
 
@@ -149,17 +145,6 @@ XBT_PUBLIC(void) xbt_throw(char* message, xbt_errcat_t errcat, int value, const
 /** @brief The display made by an exception that is not catched */
 XBT_PUBLIC(void) xbt_ex_display(xbt_ex_t * e);
 
 /** @brief The display made by an exception that is not catched */
 XBT_PUBLIC(void) xbt_ex_display(xbt_ex_t * e);
 
-/** @brief Shows a backtrace of the current location */
-XBT_PUBLIC(void) xbt_backtrace_display_current(void);
-/** @brief reimplementation of glibc backtrace based directly on gcc library, without implicit malloc  */
-XBT_PUBLIC(int) xbt_backtrace_no_malloc(void**bt, int size);
-/** @brief Captures a backtrace for further use */
-XBT_PUBLIC(void) xbt_backtrace_current(xbt_ex_t * e);
-/** @brief Display a previously captured backtrace */
-XBT_PUBLIC(void) xbt_backtrace_display(xbt_ex_t * e);
-/** @brief Get current backtrace with libunwind */
-XBT_PUBLIC(int) xbt_libunwind_backtrace(void *bt[XBT_BACKTRACE_SIZE], int size);
-
 SG_END_DECL()
 
 /** @} */
 SG_END_DECL()
 
 /** @} */
index df98adb..1d17aa2 100644 (file)
@@ -35,8 +35,6 @@ XBT_PUBLIC(void) sg_version_check(int lib_version_major,int lib_version_minor,in
 /** Contains all the parameters we got from the command line */
 XBT_PUBLIC_DATA(xbt_dynar_t) sg_cmdline;
 
 /** Contains all the parameters we got from the command line */
 XBT_PUBLIC_DATA(xbt_dynar_t) sg_cmdline;
 
-#define XBT_BACKTRACE_SIZE 10   /* FIXME: better place? Do document */
-
 /* snprintf related functions */
 /** @addtogroup XBT_str
   * @{ */
 /* snprintf related functions */
 /** @addtogroup XBT_str
   * @{ */
index 21af372..c6a3d48 100644 (file)
@@ -93,7 +93,6 @@ JavaContext::JavaContext(std::function<void()> code,
       new_exception.func = ex.func;
       new_exception.pid = ex.pid;
       new_exception.bt = ex.bt;
       new_exception.func = ex.func;
       new_exception.pid = ex.pid;
       new_exception.bt = ex.bt;
-      new_exception.bt_strings = ex.bt_strings;
       throw new_exception;
     }
   } else {
       throw new_exception;
     }
   } else {
diff --git a/src/xbt/backtrace.cpp b/src/xbt/backtrace.cpp
new file mode 100644 (file)
index 0000000..e64eab1
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (c) 2005-2016. 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/>           */
+/*  All rights reserved.                                                    */
+
+/* This code is inspirated from the OSSP version (as retrieved back in 2004)*/
+/* It was heavily modified to fit the SimGrid framework.                    */
+
+/* The OSSP version has the following copyright notice:
+**  OSSP ex - Exception Handling
+**  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/>
+**
+**  This file is part of OSSP ex, an exception handling library
+**  which can be found at http://www.ossp.org/pkg/lib/ex/.
+**
+**  Permission to use, copy, modify, and distribute this software for
+**  any purpose with or without fee is hereby granted, provided that
+**  the above copyright notice and this permission notice appear in all
+**  copies.
+**
+**  THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESSED OR IMPLIED
+**  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+**  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+**  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
+**  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+**  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+**  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+**  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+**  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+**  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+**  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+**  SUCH DAMAGE.
+ */
+
+/* The extensions made for the SimGrid project can either be distributed    */
+/* under the same license, or under the LGPL v2.1                           */
+
+#include <cstddef>
+
+#include <xbt/log.h>
+#include <xbt/backtrace.h>
+
+#include "src/internal_config.h"
+
+extern "C" {
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_backtrace, xbt, "Backtrace");
+
+}
+
+/** \brief show the backtrace of the current point (lovely while debuging) */
+void xbt_backtrace_display_current(void)
+{
+  const std::size_t size = 10;
+  xbt_backtrace_location_t bt[size];
+  size_t used = xbt_backtrace_current(bt, size);
+  xbt_backtrace_display(bt, used);
+}
+
+#if HAVE_BACKTRACE && HAVE_EXECINFO_H && HAVE_POPEN && defined(ADDR2LINE)
+# include "src/xbt/backtrace_linux.cpp"
+#else
+# include "src/xbt/backtrace_dummy.cpp"
+#endif
similarity index 73%
rename from src/xbt/backtrace_dummy.c
rename to src/xbt/backtrace_dummy.cpp
index 65a4fda..8d5c57a 100644 (file)
@@ -19,15 +19,23 @@ void xbt_backtrace_postexit(void)
 }
 
 /* create a backtrace in the given exception */
 }
 
 /* create a backtrace in the given exception */
-void xbt_backtrace_current(xbt_ex_t * e)
+size_t xbt_backtrace_current(xbt_backtrace_location_t* loc, size_t count)
 {
 {
+  return 0;
+}
+
+int xbt_backtrace_no_malloc(void **array, int size) {
+  return 0;
 }
 
 }
 
-/* prepare a backtrace for display */
-void xbt_ex_setup_backtrace(xbt_ex_t * e)
+namespace simgrid {
+namespace xbt {
+
+std::vector<std::string> resolveBacktrace(
+  xbt_backtrace_location_t* loc, std::size_t count)
 {
 {
+  return [};]
 }
 
 }
 
-int xbt_backtrace_no_malloc(void **array, int size) {
-  return 0;
 }
 }
+}
\ No newline at end of file
similarity index 65%
rename from src/xbt/backtrace_linux.c
rename to src/xbt/backtrace_linux.cpp
index 741c28f..97665f5 100644 (file)
@@ -7,12 +7,16 @@
 /* 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. */
 
 /* 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. */
 
+#include <sstream>
+
 #include <unistd.h>
 #include <execinfo.h>
 #include <sys/stat.h>
 
 /* This file is to be included in ex.cpp, so the following headers are not mandatory, but it's to make sure that eclipse see them too */
 #include <unistd.h>
 #include <execinfo.h>
 #include <sys/stat.h>
 
 /* This file is to be included in ex.cpp, so the following headers are not mandatory, but it's to make sure that eclipse see them too */
+#include <xbt/string.hpp>
 #include "xbt/ex.h"
 #include "xbt/ex.h"
+#include "src/xbt/ex_interface.h"
 #include "xbt/log.h"
 #include "xbt/str.h"
 #include "xbt/module.h"         /* xbt_binary_name */
 #include "xbt/log.h"
 #include "xbt/str.h"
 #include "xbt/module.h"         /* xbt_binary_name */
@@ -86,58 +90,45 @@ int xbt_backtrace_no_malloc(void **array, int size) {
   return arg.cnt != -1 ? arg.cnt : 0;
 }
 
   return arg.cnt != -1 ? arg.cnt : 0;
 }
 
-void xbt_backtrace_current(xbt_ex_t * e)
+size_t xbt_backtrace_current(xbt_backtrace_location_t* loc, std::size_t count)
 {
 {
-  void* bt[XBT_BACKTRACE_SIZE];
-  std::size_t used = backtrace((void **) bt, XBT_BACKTRACE_SIZE);
-  e->bt.assign(bt, bt + used);
+  std::size_t used = backtrace(loc, count);
   if (used == 0) {
   if (used == 0) {
-    fprintf(stderr, "The backtrace() function failed, which probably means that the memory is exhausted. Here is a crude dump of the exception that I was trying to build:");
-    fprintf(stderr, "%s(%d) [%s:%d] %s",
-            e->procname.c_str(), e->pid, e->file, e->line, e->what());
-    fprintf(stderr, "Bailing out now since there is nothing I can do without a decent amount of memory. Please go fix the memleaks\n");
-    exit(1);
+    std::fprintf(stderr, "The backtrace() function failed, which probably means that the memory is exhausted\n.");
+    std::fprintf(stderr, "Bailing out now since there is nothing I can do without a decent amount of memory\n.");
+    std::fprintf(stderr, "Please go fix the memleaks\n");
+    std::exit(1);
   }
   }
+  return used;
 }
 
 }
 
-void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly improved/simplifyied with http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html
-{
-  /* to get the backtrace from the libc */
-  char **backtrace_syms;
-
-  /* To build the commandline of addr2line */
-  char *cmd, *curr;
-
-  /* to extract the addresses from the backtrace */
-  char **addrs;
-  char buff[256];
-
-  /* To read the output of addr2line */
-  FILE *pipe;
-  char line_func[1024], line_pos[1024];
+namespace simgrid {
+namespace xbt {
 
 
-  /* size (in char) of pointers on this arch */
-  int addr_len = 0;
+//FIXME: This code could be greatly improved/simplifyied with
+//   http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html
+std::vector<std::string> resolveBacktrace(
+  xbt_backtrace_location_t* loc, std::size_t count)
+{
+  std::vector<std::string> result;
 
   /* To search for the right executable path when not trivial */
   struct stat stat_buf;
 
   /* To search for the right executable path when not trivial */
   struct stat stat_buf;
-  char *binary_name = NULL;
-
-  xbt_assert(e, "Backtrace not setup yet, cannot set it up for display");
-
-  e->bt_strings.clear();
 
 
-  if (xbt_binary_name == NULL) /* no binary name, nothing to do */
-    return;
+  /* no binary name, nothing to do */
+  if (xbt_binary_name == NULL)
+    return result;
 
 
-  if (e->bt.empty())
-    return;
+  if (count == 0)
+    return result;
 
 
-  /* ignore first one, which is xbt_backtrace_current() */
-  e->bt.erase(e->bt.begin());
+  // Drop the first one:
+  loc++; count--;
 
 
-  backtrace_syms = backtrace_symbols(e->bt.data(), e->bt.size());
+  char** backtrace_syms = backtrace_symbols(loc, count);
 
 
+  // Find the binary name:
+  std::string binary_name;
   /* 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 */
   /* 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 */
@@ -148,105 +139,100 @@ void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly im
         char *data;
 
         xbt_dynar_foreach(path, cpt, data) {
         char *data;
 
         xbt_dynar_foreach(path, cpt, data) {
-          free(binary_name);
-          binary_name = bprintf("%s/%s", data, xbt_binary_name);
-          if (!stat(binary_name, &stat_buf)) {
+          binary_name = simgrid::xbt::string_printf("%s/%s", data, xbt_binary_name);
+          if (!stat(binary_name.c_str(), &stat_buf)) {
             /* Found. */
             /* Found. */
-            XBT_DEBUG("Looked in the PATH for the binary. Found %s", binary_name);
+            XBT_DEBUG("Looked in the PATH for the binary. Found %s", binary_name.c_str());
             break;
           }
         }
         xbt_dynar_free(&path);
             break;
           }
         }
         xbt_dynar_free(&path);
-        if (stat(binary_name, &stat_buf)) {
+        if (stat(binary_name.c_str(), &stat_buf)) {
           /* not found */
           /* not found */
-          char* str = bprintf("(binary '%s' not found in the PATH)", xbt_binary_name);
-          e->bt_strings = {  str };
-          free(str);
+          result =  { simgrid::xbt::string_printf(
+            "(binary '%s' not found in the PATH)", xbt_binary_name) };
           free(backtrace_syms);
           free(backtrace_syms);
-          return;
+          return result;
         }
         break;
       }
     }
   } else {
         }
         break;
       }
     }
   } else {
-    binary_name = xbt_strdup(xbt_binary_name);
+    binary_name = xbt_binary_name;
   }
   }
-  int strsize = strlen(ADDR2LINE) + 25 + strlen(binary_name) + 32 * e->bt_strings.size();
-  cmd = curr = xbt_new(char, strsize);
 
 
-  curr += snprintf(curr,strsize, "%s -f -e %s ", ADDR2LINE, binary_name);
-  free(binary_name);
-
-  addrs = xbt_new(char *, e->bt.size());
-  for (std::size_t i = 0; i < e->bt.size(); i++) {
-    char *p;
+  // Create the system command for add2line:
+  std::ostringstream stream;
+  stream << ADDR2LINE << " -f -e " << binary_name << ' ';
+  std::vector<std::string> addrs(count);
+  for (std::size_t i = 0; i < count; i++) {
     /* retrieve this address */
     XBT_DEBUG("Retrieving address number %zd from '%s'", i, backtrace_syms[i]);
     /* retrieve this address */
     XBT_DEBUG("Retrieving address number %zd from '%s'", i, backtrace_syms[i]);
+    char buff[256];
     snprintf(buff, 256, "%s", strchr(backtrace_syms[i], '[') + 1);
     snprintf(buff, 256, "%s", strchr(backtrace_syms[i], '[') + 1);
-    p = strchr(buff, ']');
+    char* p = strchr(buff, ']');
     *p = '\0';
     if (strcmp(buff, "(nil)"))
     *p = '\0';
     if (strcmp(buff, "(nil)"))
-      addrs[i] = xbt_strdup(buff);
+      addrs[i] = buff;
     else
     else
-      addrs[i] = xbt_strdup("0x0");
-    XBT_DEBUG("Set up a new address: %zd, '%s'(%p)", i, addrs[i], addrs[i]);
-
+      addrs[i] = "0x0";
+    XBT_DEBUG("Set up a new address: %zd, '%s'", i, addrs[i].c_str());
     /* Add it to the command line args */
     /* Add it to the command line args */
-    curr += snprintf(curr,strsize, "%s ", addrs[i]);
+    stream << addrs[i] << ' ';
   }
   }
-  addr_len = strlen(addrs[0]);
+  binary_name.clear();
+  std::string cmd = stream.str();
 
 
-  /* parse the output and build a new backtrace */
-  e->bt_strings.resize(e->bt.size());
+  /* size (in char) of pointers on this arch */
+  int addr_len = addrs[0].size();
 
 
-  XBT_VERB("Fire a first command: '%s'", cmd);
-  pipe = popen(cmd, "r");
+  XBT_VERB("Fire a first command: '%s'", cmd.c_str());
+  FILE* pipe = popen(cmd.c_str(), "r");
   if (!pipe) {
     xbt_die("Cannot fork addr2line to display the backtrace");
   }
 
   if (!pipe) {
     xbt_die("Cannot fork addr2line to display the backtrace");
   }
 
-  for (std::size_t i = 0; i < e->bt.size(); i++) {
-    XBT_DEBUG("Looking for symbol %zd, addr = '%s'", i, addrs[i]);
+  /* To read the output of addr2line */
+  char line_func[1024], line_pos[1024];
+  for (std::size_t i = 0; i < count; i++) {
+    XBT_DEBUG("Looking for symbol %zd, addr = '%s'", i, addrs[i].c_str());
     if (fgets(line_func, 1024, pipe)) {
       line_func[strlen(line_func) - 1] = '\0';
     } else {
     if (fgets(line_func, 1024, pipe)) {
       line_func[strlen(line_func) - 1] = '\0';
     } else {
-      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i]);
+      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i].c_str());
       strncpy(line_func, "???",3);
     }
     if (fgets(line_pos, 1024, pipe)) {
       line_pos[strlen(line_pos) - 1] = '\0';
     } else {
       strncpy(line_func, "???",3);
     }
     if (fgets(line_pos, 1024, pipe)) {
       line_pos[strlen(line_pos) - 1] = '\0';
     } else {
-      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i]);
+      XBT_VERB("Cannot run fgets to look for symbol %zd, addr %s", i, addrs[i].c_str());
       strncpy(line_pos, backtrace_syms[i],1024);
     }
 
     if (strcmp("??", line_func) != 0) {
       XBT_DEBUG("Found static symbol %s() at %s", line_func, line_pos);
       strncpy(line_pos, backtrace_syms[i],1024);
     }
 
     if (strcmp("??", line_func) != 0) {
       XBT_DEBUG("Found static symbol %s() at %s", line_func, line_pos);
-      char* s = bprintf("**   In %s() at %s", line_func, line_pos);
-      e->bt_strings[i] = s;
-      free(s);
+      result.push_back(simgrid::xbt::string_printf(
+        "%s() at %s", line_func, line_pos
+      ));
     } else {
       /* Damn. The symbol is in a dynamic library. Let's get wild */
     } 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 maps_buff[512];
+      long int offset = 0;
       char *p, *p2;
       char *p, *p2;
-
-      char *subcmd;
-      FILE *subpipe;
       int found = 0;
 
       /* let's look for the offset of this library in our addressing space */
       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");
+      char* maps_name = bprintf("/proc/%d/maps", (int) getpid());
+      FILE* maps = fopen(maps_name, "r");
 
 
-      addr = strtol(addrs[i], &p, 16);
+      long int addr = strtol(addrs[i].c_str(), &p, 16);
       if (*p != '\0') {
       if (*p != '\0') {
-        XBT_CRITICAL("Cannot parse backtrace address '%s' (addr=%#lx)", addrs[i], addr);
+        XBT_CRITICAL("Cannot parse backtrace address '%s' (addr=%#lx)",
+          addrs[i].c_str(), addr);
       }
       }
-      XBT_DEBUG("addr=%s (as string) =%#lx (as number)", addrs[i], addr);
+      XBT_DEBUG("addr=%s (as string) =%#lx (as number)",
+        addrs[i].c_str(), addr);
 
       while (!found) {
         long int first, last;
 
       while (!found) {
         long int first, last;
@@ -271,14 +257,12 @@ void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly im
       }
       fclose(maps);
       free(maps_name);
       }
       fclose(maps);
       free(maps_name);
-      free(addrs[i]);
+      addrs[i].clear();
 
       if (!found) {
         XBT_VERB("Problem while reading the maps file. Following backtrace will be mangled.");
         XBT_DEBUG("No dynamic. Static symbol: %s", backtrace_syms[i]);
 
       if (!found) {
         XBT_VERB("Problem while reading the maps file. Following backtrace will be mangled.");
         XBT_DEBUG("No dynamic. Static symbol: %s", backtrace_syms[i]);
-        char* s = bprintf("**   In ?? (%s)", backtrace_syms[i]);
-        e->bt_strings[i] = s;
-        free(s);
+        result.push_back(simgrid::xbt::string_printf("?? (%s)", backtrace_syms[i]));
         continue;
       }
 
         continue;
       }
 
@@ -286,8 +270,8 @@ void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly im
          We now need to substract this from the address we got from backtrace.
        */
 
          We now need to substract this from the address we got from backtrace.
        */
 
-      addrs[i] = bprintf("0x%0*lx", addr_len - 2, addr - offset);
-      XBT_DEBUG("offset=%#lx new addr=%s", offset, addrs[i]);
+      addrs[i] = simgrid::xbt::string_printf("0x%0*lx", addr_len - 2, addr - offset);
+      XBT_DEBUG("offset=%#lx new addr=%s", offset, addrs[i].c_str());
 
       /* Got it. We have our new address. Let's get the library path and we are set */
       p = xbt_strdup(backtrace_syms[i]);
 
       /* Got it. We have our new address. Let's get the library path and we are set */
       p = xbt_strdup(backtrace_syms[i]);
@@ -304,10 +288,10 @@ void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly im
           *p2 = '\0';
 
         /* Here we go, fire an addr2line up */
           *p2 = '\0';
 
         /* Here we go, fire an addr2line up */
-        subcmd = bprintf("%s -f -e %s %s", ADDR2LINE, p, addrs[i]);
+        char* subcmd = bprintf("%s -f -e %s %s", ADDR2LINE, p, addrs[i].c_str());
         free(p);
         XBT_VERB("Fire a new command: '%s'", subcmd);
         free(p);
         XBT_VERB("Fire a new command: '%s'", subcmd);
-        subpipe = popen(subcmd, "r");
+        FILE* subpipe = popen(subcmd, "r");
         if (!subpipe) {
           xbt_die("Cannot fork addr2line to display the backtrace");
         }
         if (!subpipe) {
           xbt_die("Cannot fork addr2line to display the backtrace");
         }
@@ -330,44 +314,33 @@ void xbt_ex_setup_backtrace(xbt_ex_t * e) //FIXME: This code could be greatly im
       /* check whether the trick worked */
       if (strcmp("??", line_func)) {
         XBT_DEBUG("Found dynamic symbol %s() at %s", line_func, line_pos);
       /* check whether the trick worked */
       if (strcmp("??", line_func)) {
         XBT_DEBUG("Found dynamic symbol %s() at %s", line_func, line_pos);
-        char* s = bprintf("**   In %s() at %s", line_func, line_pos);
-        e->bt_strings[i] = s;
-        free(s);
+        result.push_back(simgrid::xbt::string_printf(
+          "%s() at %s", line_func, line_pos));
       } else {
         /* damn, nothing to do here. Let's print the raw address */
         XBT_DEBUG("Dynamic symbol not found. Raw address = %s", backtrace_syms[i]);
       } else {
         /* damn, nothing to do here. Let's print the raw address */
         XBT_DEBUG("Dynamic symbol not found. Raw address = %s", backtrace_syms[i]);
-        char* s = bprintf("**   In ?? at %s", backtrace_syms[i]);
-        e->bt_strings[i] = s;
-        free(s);
+        result.push_back(simgrid::xbt::string_printf(
+          "?? at %s", backtrace_syms[i]));
       }
     }
       }
     }
-    free(addrs[i]);
+    addrs[i].clear();
 
     /* 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"))
 
     /* 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"))
-        || !strncmp("smx_ctx_sysv_wrapper", line_func, strlen("smx_ctx_sysv_wrapper"))) {
-
-      for (std::size_t j = i + 1; j < e->bt.size(); j++)
-        free(addrs[j]);
-
-      if (!strncmp
-          ("xbt_thread_context_wrapper", line_func, strlen("xbt_thread_context_wrapper"))) {
-        e->bt_strings.push_back("**   (in a separate thread)");
-      } else {
-        e->bt_strings.push_back("");
-      }
-
-    }
+        || !strncmp("smx_ctx_sysv_wrapper", line_func, strlen("smx_ctx_sysv_wrapper")))
+      break;
   }
   pclose(pipe);
   }
   pclose(pipe);
-  free(addrs);
   free(backtrace_syms);
   free(backtrace_syms);
-  free(cmd);
+  return result;
+}
+
+}
 }
 
 #if HAVE_MC
 }
 
 #if HAVE_MC
-int xbt_libunwind_backtrace(void* bt[XBT_BACKTRACE_SIZE], int size){
+int xbt_libunwind_backtrace(void** bt, int size){
   int i = 0;
   for(i=0; i < size; i++)
     bt[i] = NULL;
   int i = 0;
   for(i=0; i < size; i++)
     bt[i] = NULL;
index 821d1ac..2fd2e3b 100644 (file)
@@ -47,6 +47,7 @@
 
 #include "src/internal_config.h"           /* execinfo when available */
 #include "xbt/ex.h"
 
 #include "src/internal_config.h"           /* execinfo when available */
 #include "xbt/ex.h"
+#include "xbt/backtrace.h"
 #include "xbt/str.h"
 #include "xbt/synchro_core.h"
 #include "src/xbt_modinter.h"       /* backtrace initialization headers */
 #include "xbt/str.h"
 #include "xbt/synchro_core.h"
 #include "src/xbt_modinter.h"       /* backtrace initialization headers */
@@ -61,43 +62,26 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex, xbt, "Exception mechanism");
 xbt_ex::~xbt_ex() {}
 
 /* Change raw libc symbols to file names and line numbers */
 xbt_ex::~xbt_ex() {}
 
 /* Change raw libc symbols to file names and line numbers */
-void xbt_ex_setup_backtrace(xbt_ex_t * e);
+void xbt_setup_backtrace(xbt_backtrace_location_t** loc, std::size_t count,
+  char** res);
 
 
-void xbt_backtrace_display(xbt_ex_t * e)
+void xbt_backtrace_display(xbt_backtrace_location_t* loc, std::size_t count)
 {
 {
-  // TODO, backtrace
-#if 0
-  xbt_ex_setup_backtrace(e);
-
 #ifdef HAVE_BACKTRACE
 #ifdef HAVE_BACKTRACE
-  if (e->bt_strings.empty()) {
+  std::vector<std::string> backtrace =
+    simgrid::xbt::resolveBacktrace(loc, count);
+  if (backtrace.empty()) {
     fprintf(stderr, "(backtrace not set)\n");
     fprintf(stderr, "(backtrace not set)\n");
-  } else {
-    fprintf(stderr, "Backtrace (displayed in process %s):\n", SIMIX_process_self_get_name());
-    for (std::string const& s : e->bt_strings) /* no need to display "xbt_backtrace_display" */
-      fprintf(stderr, "---> %s\n", s.c_str() + 4);
+    return;
   }
   }
-  xbt_ex_free(*e);
+  fprintf(stderr, "Backtrace (displayed in process %s):\n", SIMIX_process_self_get_name());
+  for (std::string const& s : backtrace)
+    fprintf(stderr, "---> %s\n", s.c_str());
 #else
   XBT_ERROR("No backtrace on this arch");
 #endif
 #else
   XBT_ERROR("No backtrace on this arch");
 #endif
-  #endif
-}
-
-/** \brief show the backtrace of the current point (lovely while debuging) */
-void xbt_backtrace_display_current(void)
-{
-  xbt_ex_t e;
-  xbt_backtrace_current(&e);
-  xbt_backtrace_display(&e);
 }
 
 }
 
-#if HAVE_BACKTRACE && HAVE_EXECINFO_H && HAVE_POPEN && defined(ADDR2LINE)
-# include "src/xbt/backtrace_linux.c"
-#else
-# include "src/xbt/backtrace_dummy.c"
-#endif
-
 void xbt_throw(
   char* message, xbt_errcat_t errcat, int value, 
   const char* file, int line, const char* func)
 void xbt_throw(
   char* message, xbt_errcat_t errcat, int value, 
   const char* file, int line, const char* func)
@@ -121,7 +105,7 @@ void xbt_ex_display(xbt_ex_t * e)
   if (e->pid != xbt_getpid())
     thrower = bprintf(" on process %d",e->pid);
 
   if (e->pid != xbt_getpid())
     thrower = bprintf(" on process %d",e->pid);
 
-  fprintf(stderr, "** SimGrid: UNCAUGHT EXCEPTION received on %s(%d): category: %s; value: %d\n"
+  std::fprintf(stderr, "** SimGrid: UNCAUGHT EXCEPTION received on %s(%d): category: %s; value: %d\n"
           "** %s\n"
           "** Thrown by %s()%s\n",
           xbt_binary_name, xbt_getpid(), xbt_ex_catname(e->category), e->value, e->what(),
           "** %s\n"
           "** Thrown by %s()%s\n",
           xbt_binary_name, xbt_getpid(), xbt_ex_catname(e->category), e->value, e->what(),
@@ -134,11 +118,11 @@ void xbt_ex_display(xbt_ex_t * e)
     return; /* Not started yet or already closing. Trying to generate a backtrace would probably fail */
   }
 
     return; /* Not started yet or already closing. Trying to generate a backtrace would probably fail */
   }
 
-  if (e->bt_strings.empty())
-    xbt_ex_setup_backtrace(e);
+  std::vector<std::string> backtrace = simgrid::xbt::resolveBacktrace(
+    e->bt.data(), e->bt.size());
 
 #ifdef HAVE_BACKTRACE
 
 #ifdef HAVE_BACKTRACE
-  if (!e->bt.empty() && !e->bt_strings.empty()) {
+  if (!backtrace.empty()) {
     /* We have everything to build neat backtraces */
     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?
     /* We have everything to build neat backtraces */
     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?
@@ -148,35 +132,31 @@ void xbt_ex_display(xbt_ex_t * e)
       // Nothing to do
     }
 
       // Nothing to do
     }
 
-    fprintf(stderr, "\n");
-    for (std::string const& s : e->bt_strings) {
+    std::fprintf(stderr, "\n");
+    for (std::string const& s : backtrace) {
 
 
+      // TODO, move this logic into solveBacktrace
       if (cutpath) {
       if (cutpath) {
-        // TODO, backtrace
-        /*
-        char* p = e->bt_strings[i];
+        // TODO, simplify this
+        char* p = xbt_strdup(s.c_str());
         xbt_str_rtrim(p, ":0123456789");
         char* filename = strrchr(p, '/')+1;
         char* end_of_message  = strrchr(p, ' ');
         xbt_str_rtrim(p, ":0123456789");
         char* filename = strrchr(p, '/')+1;
         char* end_of_message  = strrchr(p, ' ');
-
         int length = strlen(p)-strlen(end_of_message);
         int length = strlen(p)-strlen(end_of_message);
-        char* dest = malloc(length);
-
-        memcpy(dest, &p[0], length);
+        char* dest = (char*) std::malloc(length);
+        std::memcpy(dest, &p[0], length);
         dest[length] = 0;
         dest[length] = 0;
-
-        fprintf(stderr, "%s %s\n", dest, filename);
-
-        free(dest);
-        */
+        std::fprintf(stderr, "%s %s\n", dest, filename);
+        std::free(dest);
+        std::free(p);
       }
       else {
       }
       else {
-        fprintf(stderr, "%s\n", s.c_str());
+        std::fprintf(stderr, "%s\n", s.c_str());
       }
     }
   } else
 #endif
       }
     }
   } else
 #endif
-    fprintf(stderr, "\n"
+    std::fprintf(stderr, "\n"
         "**   In %s() at %s:%d\n"
         "**   (no backtrace available)\n", e->func, e->file, e->line);
 }
         "**   In %s() at %s:%d\n"
         "**   (no backtrace available)\n", e->func, e->file, e->line);
 }
index cef5284..cbff4ea 100644 (file)
 #ifndef _XBT_EX_INTERFACE_H_
 #define _XBT_EX_INTERFACE_H_
 
 #ifndef _XBT_EX_INTERFACE_H_
 #define _XBT_EX_INTERFACE_H_
 
+#include <cstddef>
+
+#include <vector>
+#include <string>
+
 #include "xbt/base.h"
 #include "xbt/base.h"
-#include "xbt/ex.h"
+#include "xbt/backtrace.h"
+
+namespace simgrid {
+namespace xbt {
 
 /* Change raw libc symbols to file names and line numbers */
 
 /* Change raw libc symbols to file names and line numbers */
-XBT_PRIVATE void xbt_ex_setup_backtrace(xbt_ex_t * e);
+XBT_PUBLIC(std::vector<std::string>) resolveBacktrace(
+  xbt_backtrace_location_t* loc, std::size_t count);
+
+}
+}
 
 #endif                          /* _XBT_EX_INTERFACE_H_ */
 
 #endif                          /* _XBT_EX_INTERFACE_H_ */
index a591421..23482c3 100644 (file)
@@ -106,6 +106,7 @@ static void xbt_log_connect_categories(void)
   XBT_LOG_CONNECT(xbt_dict_elm);
   XBT_LOG_CONNECT(xbt_dyn);
   XBT_LOG_CONNECT(xbt_ex);
   XBT_LOG_CONNECT(xbt_dict_elm);
   XBT_LOG_CONNECT(xbt_dyn);
   XBT_LOG_CONNECT(xbt_ex);
+  XBT_LOG_CONNECT(xbt_backtrace);
   XBT_LOG_CONNECT(xbt_fifo);
   XBT_LOG_CONNECT(xbt_graph);
   XBT_LOG_CONNECT(xbt_heap);
   XBT_LOG_CONNECT(xbt_fifo);
   XBT_LOG_CONNECT(xbt_graph);
   XBT_LOG_CONNECT(xbt_heap);
index 884f637..594f001 100644 (file)
@@ -8,7 +8,6 @@
 
 #include "src/internal_config.h"       /* execinfo when available */
 #include "xbt/synchro_core.h"   /* xbt_thread_self_name */
 
 #include "src/internal_config.h"       /* execinfo when available */
 #include "xbt/synchro_core.h"   /* xbt_thread_self_name */
-#include "src/xbt/ex_interface.h"
 #include "xbt/sysdep.h"
 #include "xbt/strbuff.h"
 #include "src/xbt/log_private.h"
 #include "xbt/sysdep.h"
 #include "xbt/strbuff.h"
 #include "src/xbt/log_private.h"
index 60e5e13..c66cbfc 100644 (file)
@@ -37,7 +37,6 @@
 
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
 
 #include "xbt/sysdep.h"
 #include "xbt/ex.h"
-#include "src/xbt/ex_interface.h"  /* We play crude games with exceptions */
 #include "src/internal_config.h"
 #include "xbt/xbt_os_time.h"       /* Portable time facilities */
 #include "xbt/xbt_os_thread.h"     /* This module */
 #include "src/internal_config.h"
 #include "xbt/xbt_os_time.h"       /* Portable time facilities */
 #include "xbt/xbt_os_thread.h"     /* This module */
index 3bb436d..87ef125 100644 (file)
@@ -90,8 +90,8 @@ set(EXTRA_DIST
   src/xbt/automaton/parserPromela.tab.cacc
   src/xbt/automaton/parserPromela.tab.hacc
   src/xbt/automaton/parserPromela.yacc
   src/xbt/automaton/parserPromela.tab.cacc
   src/xbt/automaton/parserPromela.tab.hacc
   src/xbt/automaton/parserPromela.yacc
-  src/xbt/backtrace_dummy.c
-  src/xbt/backtrace_linux.c
+  src/xbt/backtrace_dummy.cpp
+  src/xbt/backtrace_linux.cpp
   src/xbt/dict_private.h
   src/xbt/ex_interface.h
   src/xbt/fifo_private.h
   src/xbt/dict_private.h
   src/xbt/ex_interface.h
   src/xbt/fifo_private.h
@@ -244,6 +244,7 @@ set(XBT_SRC
   src/xbt/RngStream.c
   src/xbt/automaton/automaton.c
   src/xbt/automaton/automatonparse_promela.c
   src/xbt/RngStream.c
   src/xbt/automaton/automaton.c
   src/xbt/automaton/automatonparse_promela.c
+  src/xbt/backtrace.cpp
   src/xbt/config.cpp
   src/xbt/cunit.cpp
   src/xbt/dict.cpp
   src/xbt/config.cpp
   src/xbt/cunit.cpp
   src/xbt/dict.cpp
@@ -666,6 +667,7 @@ set(headers_to_install
   include/xbt/dynar.h
   include/xbt/dynar.hpp
   include/xbt/ex.h
   include/xbt/dynar.h
   include/xbt/dynar.hpp
   include/xbt/ex.h
+  include/xbt/backtrace.h
   include/xbt/fifo.h
   include/xbt/file.h
   include/xbt/function_types.h
   include/xbt/fifo.h
   include/xbt/file.h
   include/xbt/function_types.h