/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
*
- * libmcachedd client library.
+ * Libmemcached client library.
*
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ * Copyright (C) 2012 Data Differential, http://datadifferential.com/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
*
*/
-#include <libmemcached/common.h>
+#include "mem_config.h"
-#ifdef AX_ENABLE_BACKTRACE
+#include "libmemcached/backtrace.hpp"
-#ifdef HAVE_EXECINFO_H
-# include <execinfo.h>
-#endif
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
-#ifdef HAVE_GCC_ABI_DEMANGLE
-# include <cxxabi.h>
-#endif
+#if defined(HAVE_SHARED_ENABLED) && HAVE_SHARED_ENABLED
-#ifdef HAVE_DLFCN_H
-# include <dlfcn.h>
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
#endif
#ifdef HAVE_GCC_ABI_DEMANGLE
+# include <cxxabi.h>
# define USE_DEMANGLE 1
#else
# define USE_DEMANGLE 0
#endif
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
const int MAX_DEPTH= 50;
void custom_backtrace(void)
{
#ifdef HAVE_EXECINFO_H
- void *array[MAX_DEPTH];
-
- int backtrace_size= backtrace(array, MAX_DEPTH);
- fprintf(stderr, "Number of stack frames obtained: %d\n", backtrace_size);
+ void *backtrace_buffer[MAX_DEPTH +1];
-#ifdef HAVE_DLFCN_H
- Dl_info dlinfo;
-#endif
+ int stack_frames= backtrace(backtrace_buffer, MAX_DEPTH);
+ if (stack_frames)
+ {
+ char **symbollist= backtrace_symbols(backtrace_buffer, stack_frames);
+ if (symbollist)
+ {
+ for (int x= 0; x < stack_frames; x++)
+ {
+ bool was_demangled= false;
- for (int x= 0; x < backtrace_size; ++x)
- {
+ if (USE_DEMANGLE)
+ {
#ifdef HAVE_DLFCN_H
- if (dladdr(array[x], &dlinfo) == 0)
- {
- continue;
- }
+ Dl_info dlinfo;
+ if (dladdr(backtrace_buffer[x], &dlinfo))
+ {
+ char demangled_buffer[1024];
+ const char *called_in= "<unresolved>";
+ if (dlinfo.dli_sname)
+ {
+ size_t demangled_size= sizeof(demangled_buffer);
+ int status;
+ char* demangled;
+ if ((demangled= abi::__cxa_demangle(dlinfo.dli_sname, demangled_buffer, &demangled_size, &status)))
+ {
+ called_in= demangled;
+ fprintf(stderr, "---> demangled: %s -> %s\n", demangled_buffer, demangled);
+ }
+ else
+ {
+ called_in= dlinfo.dli_sname;
+ }
+
+ was_demangled= true;
+ fprintf(stderr, "#%d %p in %s at %s\n",
+ x, backtrace_buffer[x],
+ called_in,
+ dlinfo.dli_fname);
+ }
+ }
#endif
+ }
- const char* symname= dlinfo.dli_sname;
-
- int status;
- char* demangled= abi::__cxa_demangle(symname, NULL, 0, &status);
- if (status == 0 and demangled)
- {
- symname= demangled;
- }
-
- printf("object: %s, function: %s\n", dlinfo.dli_fname, symname);
+ if (was_demangled == false)
+ {
+ fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]);
+ }
+ }
- if (demangled)
- {
- free(demangled);
+ ::free(symbollist);
}
- }
+ }
#endif // HAVE_EXECINFO_H
+}
+
+#else // HAVE_SHARED_ENABLED
-#else // AX_ENABLE_BACKTRACE
void custom_backtrace(void)
{
+ fprintf(stderr, "Backtrace null function called\n");
}
#endif // AX_ENABLE_BACKTRACE