Demangle and pretty-print symbols in internal backtraces. Patch by
authorDan Gohman <gohman@apple.com>
Fri, 5 Dec 2008 20:12:48 +0000 (20:12 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 5 Dec 2008 20:12:48 +0000 (20:12 +0000)
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

lib/System/Unix/Signals.inc

index 4e0e6d22fd9e9c04ed2befcf87bf2aa56e7c3d78..abb6a3363772ea45a88721cfba7fde750d13b957 100644 (file)
 #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...