X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fbacktrace.cc;h=e171fbeba360b30142083e4c4769944379e5ba79;hb=411d5ae2fdcd66d8613d38c3725e4ef76f022fea;hp=bc8846bae820703799945342223cb968547f30f0;hpb=0a45c8bafd621482cb08f2e5f792f42cafb13865;p=awesomized%2Flibmemcached diff --git a/libmemcached/backtrace.cc b/libmemcached/backtrace.cc index bc8846ba..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,74 +35,97 @@ * */ -#include +#include "mem_config.h" -#include +#include "libmemcached/backtrace.hpp" + +#include #include +#include -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE +#if defined(HAVE_SHARED_ENABLED) && HAVE_SHARED_ENABLED + +#ifdef HAVE_EXECINFO_H #include -#include -#endif // HAVE_BACKTRACE -#endif // __GNUC__ +#endif + +#ifdef HAVE_GCC_ABI_DEMANGLE +# include +# define USE_DEMANGLE 1 +#else +# define USE_DEMANGLE 0 +#endif + +#ifdef HAVE_DLFCN_H +# include +#endif +const int MAX_DEPTH= 50; void custom_backtrace(void) { -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE - void *array[50]; +#ifdef HAVE_EXECINFO_H + void *backtrace_buffer[MAX_DEPTH +1]; - size_t size= backtrace(array, 50); - char **strings= backtrace_symbols(array, size); + 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; - fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size); + if (USE_DEMANGLE) + { +#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; + } - for (size_t x= 1; x < size; x++) - { - size_t sz= 200; - char *function= (char *)malloc(sz); - char *begin= 0; - char *end= 0; + was_demangled= true; + fprintf(stderr, "#%d %p in %s at %s\n", + x, backtrace_buffer[x], + called_in, + dlinfo.dli_fname); + } + } +#endif + } - for (char *j = strings[x]; *j; ++j) - { - if (*j == '(') { - begin = j; - } - else if (*j == '+') { - end = j; + if (was_demangled == false) + { + fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]); + } } - } - if (begin && end) - { - begin++; - *end= '\0'; - 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); + ::free(symbollist); } - else - { - fprintf(stderr, "%s\n", strings[x]); - } - free(function); } +#endif // HAVE_EXECINFO_H +} +#else // HAVE_SHARED_ENABLED - free (strings); -#endif // HAVE_BACKTRACE -#endif // __GNUC__ +void custom_backtrace(void) +{ + fprintf(stderr, "Backtrace null function called\n"); } +#endif // AX_ENABLE_BACKTRACE