From 243250c239ad63904a0ea22d3247d1e683bc7fa0 Mon Sep 17 00:00:00 2001 From: Farooq Mela Date: Sat, 4 May 2013 14:01:15 -0700 Subject: [PATCH 1/2] Demangle C++ stack trace symbols for more readable stack traces. --- src/mongo/util/stacktrace.cpp | 72 ++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 22 deletions(-) diff --git a/src/mongo/util/stacktrace.cpp b/src/mongo/util/stacktrace.cpp index ab405c9a71706..e19140db87a78 100644 --- a/src/mongo/util/stacktrace.cpp +++ b/src/mongo/util/stacktrace.cpp @@ -22,38 +22,66 @@ #ifdef MONGO_HAVE_EXECINFO_BACKTRACE -#include +#include /* For backtrace() and backtrace_symbols() */ +#include /* For dladdr() */ +#ifdef __GNUC__ +#include /* For __cxa_demangle() */ +#endif namespace mongo { static const int maxBackTraceFrames = 20; /** * Print a stack backtrace for the current thread to the specified ostream. - * + * * @param os ostream& to receive printed stack backtrace */ void printStackTrace( std::ostream& os ) { - - void *b[maxBackTraceFrames]; - - int size = ::backtrace( b, maxBackTraceFrames ); + + void *callstack[maxBackTraceFrames]; + + const int size = ::backtrace( callstack, maxBackTraceFrames ); for ( int i = 0; i < size; i++ ) - os << std::hex << b[i] << std::dec << ' '; + os << std::hex << callstack[i] << std::dec << ' '; os << std::endl; - - char **strings; - - strings = ::backtrace_symbols( b, size ); - if (strings == NULL) { + + char **symbols = ::backtrace_symbols( callstack, size ); + if (symbols == NULL) { const int err = errno; os << "Unable to collect backtrace symbols (" << errnoWithDescription(err) << ")" << std::endl; - return; } - for ( int i = 0; i < size; i++ ) - os << ' ' << strings[i] << '\n'; + for ( int i = 0; i < size; i++ ) { + char buf[1024]; + Dl_info info; + if (dladdr(callstack[i], &info) && info.dli_sname) { + char *demangled = NULL; + int status = -1; +#ifdef __GNUC__ + if (info.dli_sname[0] == '_') + demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); +#endif + const char *symbol = (status == 0) ? demangled : info.dli_sname; + snprintf(buf, sizeof(buf), " %-3d %*p %s + %zd\n", + i, int(2 + sizeof(void*) * 2), callstack[i], symbol, + (char *)callstack[i] - (char *)info.dli_saddr); + free(demangled); + } else { + const char *symbol = (symbols != NULL) ? strstr(symbols[i], "0x") : NULL; + if (symbol) { + /* Skip over the address and get the mangled name. */ + while (!isspace(*symbol++)) + ; + } else { + symbol = "???"; + } + snprintf(buf, sizeof(buf), " %-3d %*p %s\n", + i, int(2 + sizeof(void*) * 2), callstack[i], symbol); + } + os << buf; + } os.flush(); - ::free( strings ); + ::free( symbols ); } } @@ -63,7 +91,7 @@ namespace mongo { /** * Get the path string to be used when searching for PDB files. - * + * * @param process Process handle * @return searchPath Returned search path string */ @@ -83,7 +111,7 @@ namespace mongo { /** * Get the display name of the executable module containing the specified address. - * + * * @param process Process handle * @param address Address to find * @param returnedModuleName Returned module name @@ -107,7 +135,7 @@ namespace mongo { /** * Get the display name and line number of the source file containing the specified address. - * + * * @param process Process handle * @param address Address to find * @param returnedSourceAndLine Returned source code file name with line number @@ -144,7 +172,7 @@ namespace mongo { /** * Get the display text of the symbol and offset of the specified address. - * + * * @param process Process handle * @param address Address to find * @param symbolInfo Caller's pre-built SYMBOL_INFO struct (for efficiency) @@ -178,7 +206,7 @@ namespace mongo { /** * Print a stack backtrace for the current thread to the specified ostream. - * + * * @param os ostream& to receive printed stack backtrace */ void printStackTrace( std::ostream& os ) { @@ -193,7 +221,7 @@ namespace mongo { /** * Print stack trace (using a specified stack context) to "os" - * + * * @param context CONTEXT record for stack trace * @param os ostream& to receive printed stack backtrace */ From 3df8fd841dc5ec9a8ead96c9ef2cc30e69ad8c94 Mon Sep 17 00:00:00 2001 From: Farooq Mela Date: Sun, 5 May 2013 15:03:57 -0700 Subject: [PATCH 2/2] Fix formatting (use spaces, not tabs). --- src/mongo/util/stacktrace.cpp | 58 +++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/mongo/util/stacktrace.cpp b/src/mongo/util/stacktrace.cpp index e19140db87a78..9a692ac6cb168 100644 --- a/src/mongo/util/stacktrace.cpp +++ b/src/mongo/util/stacktrace.cpp @@ -22,10 +22,10 @@ #ifdef MONGO_HAVE_EXECINFO_BACKTRACE -#include /* For backtrace() and backtrace_symbols() */ -#include /* For dladdr() */ +#include /* For backtrace() and backtrace_symbols() */ +#include /* For dladdr() */ #ifdef __GNUC__ -#include /* For __cxa_demangle() */ +#include /* For __cxa_demangle() */ #endif namespace mongo { @@ -52,34 +52,34 @@ namespace mongo { << std::endl; } for ( int i = 0; i < size; i++ ) { - char buf[1024]; - Dl_info info; - if (dladdr(callstack[i], &info) && info.dli_sname) { - char *demangled = NULL; - int status = -1; + char buf[1024]; + Dl_info info; + if (dladdr(callstack[i], &info) && info.dli_sname) { + char *demangled = NULL; + int status = -1; #ifdef __GNUC__ - if (info.dli_sname[0] == '_') - demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); + if (info.dli_sname[0] == '_') + demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); #endif - const char *symbol = (status == 0) ? demangled : info.dli_sname; - snprintf(buf, sizeof(buf), " %-3d %*p %s + %zd\n", - i, int(2 + sizeof(void*) * 2), callstack[i], symbol, - (char *)callstack[i] - (char *)info.dli_saddr); - free(demangled); - } else { - const char *symbol = (symbols != NULL) ? strstr(symbols[i], "0x") : NULL; - if (symbol) { - /* Skip over the address and get the mangled name. */ - while (!isspace(*symbol++)) - ; - } else { - symbol = "???"; - } - snprintf(buf, sizeof(buf), " %-3d %*p %s\n", - i, int(2 + sizeof(void*) * 2), callstack[i], symbol); - } - os << buf; - } + const char *symbol = (status == 0) ? demangled : info.dli_sname; + snprintf(buf, sizeof(buf), " %-3d %*p %s + %zd\n", + i, int(2 + sizeof(void*) * 2), callstack[i], symbol, + (char *)callstack[i] - (char *)info.dli_saddr); + free(demangled); + } else { + const char *symbol = (symbols != NULL) ? strstr(symbols[i], "0x") : NULL; + if (symbol) { + /* Skip over the address and get the mangled name. */ + while (!isspace(*symbol++)) + ; + } else { + symbol = "???"; + } + snprintf(buf, sizeof(buf), " %-3d %*p %s\n", + i, int(2 + sizeof(void*) * 2), callstack[i], symbol); + } + os << buf; + } os.flush(); ::free( symbols ); }