Remove another chunck of Pandora.
[awesomized/libmemcached] / libmemcached / backtrace.cc
index 871f27afb762d3151e192cc9f5367e3909262e06..81cfddefcc94d69fe014b3154f46c228b330ecdd 100644 (file)
 
 #include <cstring>
 #include <cstdlib>
+#include <cstdio>
 
 #ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
+#  include <execinfo.h>
 #endif
 
-#ifdef HAVE_CXXABI_H
-#include <cxxabi.h>
+#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
+#  define USE_DEMANGLE 1
 #else
-#define USE_DEMANGLE 0
+#  define USE_DEMANGLE 0
 #endif
 
+const int MAX_DEPTH= 50;
+
 void custom_backtrace(void)
 {
 #ifdef HAVE_EXECINFO_H
-  void *array[50];
+  void *array[MAX_DEPTH];
 
-  int 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);
 
-  if (strings == NULL)
-  {
-    return;
-  }
-
-  fprintf(stderr, "Number of stack frames obtained: %d\n", size);
-
-  char *named_function= (char *)std::realloc(NULL, 1024);
-  
-  if (named_function == NULL)
-  {
-    std::free(strings);
-    return;
-  }
+#ifdef HAVE_DLFCN_H
+  Dl_info dlinfo;
+#endif
 
-  for (int x= 1; x < size; x++) 
-  {
-    if (USE_DEMANGLE)
+  for (int x= 0; x < backtrace_size; ++x)
+  {  
+#ifdef HAVE_DLFCN_H
+    if (dladdr(array[x], &dlinfo) == 0)
     {
-      size_t sz= 200;
-      char *named_function_ptr= (char *)std::realloc(named_function, sz);
-      if (named_function_ptr == NULL)
-      {
-        continue;
-      }
-      named_function= named_function_ptr;
+      continue;
+    }
+#endif
 
-      char *begin_name= 0;
-      char *begin_offset= 0;
-      char *end_offset= 0;
+    const char* symname= dlinfo.dli_sname;
 
-      for (char *j= strings[x]; *j; ++j)
-      {
-        if (*j == '(')
-        {
-          begin_name= j;
-        }
-        else if (*j == '+')
-        {
-          begin_offset= j;
-        }
-        else if (*j == ')' and begin_offset) 
-        {
-          end_offset= j;
-          break;
-        }
-      }
+    int status;
+    char* demangled= abi::__cxa_demangle(symname, NULL, 0, &status);
+    if (status == 0 and demangled)
+    {
+      symname= demangled;
+    }
 
-      if (begin_name and begin_offset and end_offset and begin_name < begin_offset)
-      {
-        *begin_name++= '\0';
-        *begin_offset++= '\0';
-        *end_offset= '\0';
+    printf("object: %s, function: %s\n", dlinfo.dli_fname, symname);
 
-        int status;
-        char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status);
-        if (ret) // realloc()'ed string
-        {
-          named_function= ret;
-          fprintf(stderr, "  %s : %s()+%s\n", strings[x], begin_name, begin_offset);
-        }
-        else
-        {
-          fprintf(stderr, "  %s : %s()+%s\n", strings[x], begin_name, begin_offset);
-        }
-      }
-      else
-      {
-        fprintf(stderr, " %s\n", strings[x]);
-      }
-    }
-    else
+    if (demangled)
     {
-      fprintf(stderr, " unmangled: %s\n", strings[x]);
+      free(demangled);
     }
-  }
-
-  std::free(named_function);
-  std::free(strings);
+  } 
 #endif // HAVE_EXECINFO_H
 }