summaryrefslogtreecommitdiff
path: root/lib/System/Unix/Signals.inc
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-12-05 20:12:48 +0000
committerDan Gohman <gohman@apple.com>2008-12-05 20:12:48 +0000
commit56d9b6dff34c7f934786aa996d94c9f5d7b0c0c9 (patch)
tree19025a3637fde7199e2ac1973509f4e2b801ab95 /lib/System/Unix/Signals.inc
parent64b535608e03531e0a0a5745724b7e8d819bdd71 (diff)
downloadllvm-56d9b6dff34c7f934786aa996d94c9f5d7b0c0c9.tar.gz
llvm-56d9b6dff34c7f934786aa996d94c9f5d7b0c0c9.tar.bz2
llvm-56d9b6dff34c7f934786aa996d94c9f5d7b0c0c9.tar.xz
Demangle and pretty-print symbols in internal backtraces. Patch by
Wesley Peck, with a few fixes by me. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60605 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/System/Unix/Signals.inc')
-rw-r--r--lib/System/Unix/Signals.inc44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index 4e0e6d22fd..abb6a33637 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -25,6 +25,10 @@
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#if HAVE_DLFCN_H && __GNUG__
+#include <dlfcn.h>
+#include <cxxabi.h>
+#endif
using namespace llvm;
namespace {
@@ -69,8 +73,48 @@ static void PrintStackTrace() {
// Use backtrace() to output a backtrace on Linux systems with glibc.
int depth = backtrace(StackTrace,
static_cast<int>(array_lengthof(StackTrace)));
+#if HAVE_DLFCN_H && __GNUG__
+ int width = 0;
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+ char* name = strrchr(dlinfo.dli_fname, '/');
+
+ int nwidth;
+ if (name == NULL) nwidth = strlen(dlinfo.dli_fname);
+ else nwidth = strlen(name) - 1;
+
+ if (nwidth > width) width = nwidth;
+ }
+
+ for (int i = 0; i < depth; ++i) {
+ Dl_info dlinfo;
+ dladdr(StackTrace[i], &dlinfo);
+
+ fprintf(stderr, "%-3d", i);
+
+ char* name = strrchr(dlinfo.dli_fname, '/');
+ if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
+ else fprintf(stderr, " %-*s", width, name+1);
+
+ fprintf(stderr, " %#0*x", (int)(sizeof(void*) * 2) + 2, StackTrace[i]);
+
+ if (dlinfo.dli_sname != NULL) {
+ int res;
+ fputc(' ', stderr);
+ char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
+ if (d == NULL) fputs(dlinfo.dli_sname, stderr);
+ else fputs(d, stderr);
+ free(d);
+
+ fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
+ }
+ fputc('\n', stderr);
+ }
+#else
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
#endif
+#endif
}
// SignalHandler - The signal handler that runs...