--- /dev/null
+/* 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
-/* ex - Exception Handling */
-
/* Copyright (c) 2005-2015. The SimGrid Team.
* All rights reserved. */
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
/** @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()
/** @} */
/** 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
* @{ */
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 {
--- /dev/null
+/* 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
}
/* 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
/* 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 <xbt/string.hpp>
#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 */
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) {
- 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;
- 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 */
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. */
- 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);
- if (stat(binary_name, &stat_buf)) {
+ if (stat(binary_name.c_str(), &stat_buf)) {
/* 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);
- return;
+ return result;
}
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]);
+ char buff[256];
snprintf(buff, 256, "%s", strchr(backtrace_syms[i], '[') + 1);
- p = strchr(buff, ']');
+ char* p = strchr(buff, ']');
*p = '\0';
if (strcmp(buff, "(nil)"))
- addrs[i] = xbt_strdup(buff);
+ addrs[i] = buff;
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 */
- 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");
}
- 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 {
- 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 {
- 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);
- 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 */
- 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 *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");
+ 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') {
- 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;
}
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]);
- 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;
}
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]);
*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);
- subpipe = popen(subcmd, "r");
+ FILE* subpipe = popen(subcmd, "r");
if (!subpipe) {
xbt_die("Cannot fork addr2line to display the backtrace");
}
/* 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]);
- 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"))
- || !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);
- free(addrs);
free(backtrace_syms);
- free(cmd);
+ return result;
+}
+
+}
}
#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;
#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 */
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
- if (e->bt_strings.empty()) {
+ std::vector<std::string> backtrace =
+ simgrid::xbt::resolveBacktrace(loc, count);
+ if (backtrace.empty()) {
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
- #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)
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(),
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
- 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?
// 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) {
- // 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, ' ');
-
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;
-
- fprintf(stderr, "%s %s\n", dest, filename);
-
- free(dest);
- */
+ std::fprintf(stderr, "%s %s\n", dest, filename);
+ std::free(dest);
+ std::free(p);
}
else {
- fprintf(stderr, "%s\n", s.c_str());
+ std::fprintf(stderr, "%s\n", s.c_str());
}
}
} 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);
}
#ifndef _XBT_EX_INTERFACE_H_
#define _XBT_EX_INTERFACE_H_
+#include <cstddef>
+
+#include <vector>
+#include <string>
+
#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 */
-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_ */
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);
#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/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 */
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/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
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