X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fbacktrace.cc;h=e171fbeba360b30142083e4c4769944379e5ba79;hb=411d5ae2fdcd66d8613d38c3725e4ef76f022fea;hp=3924e0b0ab27ffecfae5e52c3a21b990392e22e8;hpb=5abb93aa2fc9d32eda20c84cc9c04056789c056e;p=awesomized%2Flibmemcached diff --git a/libmemcached/backtrace.cc b/libmemcached/backtrace.cc index 3924e0b0..e171fbeb 100644 --- a/libmemcached/backtrace.cc +++ b/libmemcached/backtrace.cc @@ -1,8 +1,8 @@ /* 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 @@ -35,111 +35,97 @@ * */ -#include +#include "mem_config.h" -#include +#include "libmemcached/backtrace.hpp" + +#include #include +#include + +#if defined(HAVE_SHARED_ENABLED) && HAVE_SHARED_ENABLED #ifdef HAVE_EXECINFO_H #include #endif -#ifdef HAVE_CXXABI_H -#include -#endif - #ifdef HAVE_GCC_ABI_DEMANGLE -#define USE_DEMANGLE 1 +# include +# define USE_DEMANGLE 1 #else -#define USE_DEMANGLE 0 +# define USE_DEMANGLE 0 #endif +#ifdef HAVE_DLFCN_H +# include +#endif + +const int MAX_DEPTH= 50; + void custom_backtrace(void) { #ifdef HAVE_EXECINFO_H - void *array[50]; - - size_t size= backtrace(array, 50); - char **strings= backtrace_symbols(array, size); - - if (strings == NULL) - { - return; - } - - fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size); - - char *named_function= (char *)std::realloc(NULL, 1024); - - if (named_function == NULL) - { - std::free(strings); - return; - } + void *backtrace_buffer[MAX_DEPTH +1]; - for (size_t x= 1; x < size; x++) + int stack_frames= backtrace(backtrace_buffer, MAX_DEPTH); + if (stack_frames) { - if (USE_DEMANGLE) + char **symbollist= backtrace_symbols(backtrace_buffer, stack_frames); + if (symbollist) { - size_t sz= 200; - char *named_function_ptr= (char *)std::realloc(named_function, sz); - if (named_function_ptr == NULL) + for (int x= 0; x < stack_frames; x++) { - continue; - } - named_function= named_function_ptr; - - char *begin_name= 0; - char *begin_offset= 0; - char *end_offset= 0; + bool was_demangled= false; - for (char *j= strings[x]; *j; ++j) - { - if (*j == '(') - { - begin_name= j; - } - else if (*j == '+') - { - begin_offset= j; - } - else if (*j == ')' and begin_offset) + if (USE_DEMANGLE) { - end_offset= j; - break; +#ifdef HAVE_DLFCN_H + Dl_info dlinfo; + if (dladdr(backtrace_buffer[x], &dlinfo)) + { + char demangled_buffer[1024]; + const char *called_in= ""; + 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 } - } - if (begin_name and begin_offset and end_offset and begin_name < begin_offset) - { - *begin_name++= '\0'; - *begin_offset++= '\0'; - *end_offset= '\0'; - - int status; - char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status); - if (ret) // realloc()'ed string + if (was_demangled == false) { - named_function= ret; - fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset); + fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]); } - else - { - fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset); - } - } - else - { - fprintf(stderr, " %s\n", strings[x]); } - } - else - { - fprintf(stderr, " unmangled: %s\n", strings[x]); + + ::free(symbollist); } } - - std::free(named_function); - std::free(strings); #endif // HAVE_EXECINFO_H } + +#else // HAVE_SHARED_ENABLED + +void custom_backtrace(void) +{ + fprintf(stderr, "Backtrace null function called\n"); +} +#endif // AX_ENABLE_BACKTRACE