Remove another chunck of Pandora.
[m6w6/libmemcached] / libmemcached / backtrace.cc
index bc8846bae820703799945342223cb968547f30f0..81cfddefcc94d69fe014b3154f46c228b330ecdd 100644 (file)
 
 #include <cstring>
 #include <cstdlib>
+#include <cstdio>
 
-#ifdef __GNUC__
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-#include <cxxabi.h>
-#endif // HAVE_BACKTRACE
-#endif // __GNUC__
+#ifdef HAVE_EXECINFO_H
+#  include <execinfo.h>
+#endif
 
+#ifdef HAVE_GCC_ABI_DEMANGLE
+#  include <cxxabi.h>
+#endif
+
+#ifdef HAVE_DLFCN_H
+#  include <dlfcn.h>
+#endif
+
+#ifdef HAVE_GCC_ABI_DEMANGLE
+#  define USE_DEMANGLE 1
+#else
+#  define USE_DEMANGLE 0
+#endif
+
+const int MAX_DEPTH= 50;
 
 void custom_backtrace(void)
 {
-#ifdef __GNUC__
-#ifdef HAVE_BACKTRACE
-  void *array[50];
+#ifdef HAVE_EXECINFO_H
+  void *array[MAX_DEPTH];
 
-  size_t size= backtrace(array, 50);
-  char **strings= backtrace_symbols(array, size);
+  int backtrace_size= backtrace(array, MAX_DEPTH);
+  fprintf(stderr, "Number of stack frames obtained: %d\n", backtrace_size);
 
-  fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size);
+#ifdef HAVE_DLFCN_H
+  Dl_info dlinfo;
+#endif
 
-  for (size_t x= 1; x < size; x++) 
-  {
-    size_t sz= 200;
-    char *function= (char *)malloc(sz);
-    char *begin= 0;
-    char *end= 0;
-
-    for (char *j = strings[x]; *j; ++j)
+  for (int x= 0; x < backtrace_size; ++x)
+  {  
+#ifdef HAVE_DLFCN_H
+    if (dladdr(array[x], &dlinfo) == 0)
     {
-      if (*j == '(') {
-        begin = j;
-      }
-      else if (*j == '+') {
-        end = j;
-      }
+      continue;
     }
-    if (begin && end)
-    {
-      begin++;
-      *end= '\0';
+#endif
 
-      int status;
-      char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
-      if (ret) 
-      {
-        function= ret;
-      }
-      else
-      {
-        strncpy(function, begin, sz);
-        strncat(function, "()", sz);
-        function[sz-1] = '\0';
-      }
-      fprintf(stderr, "%s\n", function);
-    }
-    else
+    const char* symname= dlinfo.dli_sname;
+
+    int status;
+    char* demangled= abi::__cxa_demangle(symname, NULL, 0, &status);
+    if (status == 0 and demangled)
     {
-      fprintf(stderr, "%s\n", strings[x]);
+      symname= demangled;
     }
-    free(function);
-  }
 
+    printf("object: %s, function: %s\n", dlinfo.dli_fname, symname);
 
-  free (strings);
-#endif // HAVE_BACKTRACE
-#endif // __GNUC__
+    if (demangled)
+    {
+      free(demangled);
+    }
+  } 
+#endif // HAVE_EXECINFO_H
 }