X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=libmemcached%2Fbacktrace.cc;h=3924e0b0ab27ffecfae5e52c3a21b990392e22e8;hb=09b4ff9a9b7c62b4511ab10c9305eba757fea34b;hp=bc8846bae820703799945342223cb968547f30f0;hpb=3e4c141a6b0ec12b668143a26ecf01da5c151931;p=m6w6%2Flibmemcached diff --git a/libmemcached/backtrace.cc b/libmemcached/backtrace.cc index bc8846ba..3924e0b0 100644 --- a/libmemcached/backtrace.cc +++ b/libmemcached/backtrace.cc @@ -40,69 +40,106 @@ #include #include -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE +#ifdef HAVE_EXECINFO_H #include +#endif + +#ifdef HAVE_CXXABI_H #include -#endif // HAVE_BACKTRACE -#endif // __GNUC__ +#endif +#ifdef HAVE_GCC_ABI_DEMANGLE +#define USE_DEMANGLE 1 +#else +#define USE_DEMANGLE 0 +#endif void custom_backtrace(void) { -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE +#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); - for (size_t x= 1; x < size; x++) + char *named_function= (char *)std::realloc(NULL, 1024); + + if (named_function == NULL) { - size_t sz= 200; - char *function= (char *)malloc(sz); - char *begin= 0; - char *end= 0; + std::free(strings); + return; + } - for (char *j = strings[x]; *j; ++j) + for (size_t x= 1; x < size; x++) + { + if (USE_DEMANGLE) { - if (*j == '(') { - begin = j; + size_t sz= 200; + char *named_function_ptr= (char *)std::realloc(named_function, sz); + if (named_function_ptr == NULL) + { + continue; } - else if (*j == '+') { - end = j; + named_function= named_function_ptr; + + char *begin_name= 0; + char *begin_offset= 0; + char *end_offset= 0; + + 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; + } } - } - if (begin && end) - { - begin++; - *end= '\0'; - int status; - char *ret = abi::__cxa_demangle(begin, function, &sz, &status); - if (ret) + if (begin_name and begin_offset and end_offset and begin_name < begin_offset) { - function= ret; + *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 + { + 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 { - strncpy(function, begin, sz); - strncat(function, "()", sz); - function[sz-1] = '\0'; + fprintf(stderr, " %s\n", strings[x]); } - fprintf(stderr, "%s\n", function); } else { - fprintf(stderr, "%s\n", strings[x]); + fprintf(stderr, " unmangled: %s\n", strings[x]); } - free(function); } - - free (strings); -#endif // HAVE_BACKTRACE -#endif // __GNUC__ + std::free(named_function); + std::free(strings); +#endif // HAVE_EXECINFO_H }