GCC/Unix: Try to demangle C++ function names in crashlog stack trace.

Change format of stack trace lines to improve readability.
This commit is contained in:
Jonathan G Rennison
2015-09-08 00:49:34 +01:00
parent 54eb340998
commit 387bf403da
2 changed files with 57 additions and 0 deletions

View File

@@ -1554,6 +1554,37 @@ make_cflags_and_ldflags() {
if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then
LIBS="$LIBS -lpthread" LIBS="$LIBS -lpthread"
fi fi
if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ] && [ "$os" != "PSP" ] && [ "$os" != "OS2" ]; then
"$cc_host" -o /dev/null -x c++ - -ldl 2> /dev/null << EOL
#include <dlfcn.h>
int main() {
Dl_info info;
return dladdr(0, &info);
}
EOL
if [ $? -ne 0 ]; then
log 1 "checking libdl... no"
else
log 1 "checking libdl... found"
LIBS="$LIBS -ldl"
CFLAGS="$CFLAGS -DWITH_DL"
fi
"$cc_host" -o /dev/null -x c++ - -lstdc++ 2> /dev/null << EOL
#include <cxxabi.h>
int main() {
int status = -1;
char *demangled = abi::__cxa_demangle("test", 0, 0, &status);
return 0;
}
EOL
if [ $? -ne 0 ]; then
log 1 "checking abi::__cxa_demangle... no"
else
log 1 "checking abi::__cxa_demangle... found"
CFLAGS="$CFLAGS -DWITH_DEMANGLE"
fi
fi
if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ]; then if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "DOS" ] && [ "$os" != "WINCE" ]; then
LIBS="$LIBS -lc" LIBS="$LIBS -lc"

View File

@@ -22,6 +22,12 @@
#if defined(__GLIBC__) #if defined(__GLIBC__)
/* Execinfo (and thus making stacktraces) is a GNU extension */ /* Execinfo (and thus making stacktraces) is a GNU extension */
# include <execinfo.h> # include <execinfo.h>
#if defined(WITH_DL)
# include <dlfcn.h>
#endif
#if defined(WITH_DEMANGLE)
# include <cxxabi.h>
#endif
#elif defined(SUNOS) #elif defined(SUNOS)
# include <ucontext.h> # include <ucontext.h>
# include <dlfcn.h> # include <dlfcn.h>
@@ -114,6 +120,26 @@ class CrashLogUnix : public CrashLog {
char **messages = backtrace_symbols(trace, trace_size); char **messages = backtrace_symbols(trace, trace_size);
for (int i = 0; i < trace_size; i++) { for (int i = 0; i < trace_size; i++) {
#if defined(WITH_DL)
Dl_info info;
int dladdr_result = dladdr(trace[i], &info);
if (dladdr_result && info.dli_sname) {
int status = -1;
char *demangled = NULL;
#if defined(WITH_DEMANGLE)
demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
#endif
const char *name = (demangled != NULL && status == 0) ? demangled : info.dli_sname;
buffer += seprintf(buffer, last, " [%02i] %*p %-40s %s + 0x%zx\n", i, int(2 + sizeof(void*) * 2),
trace[i], info.dli_fname, name, (char *)trace[i] - (char *)info.dli_saddr);
free(demangled);
continue;
} else if (dladdr_result && info.dli_fname) {
buffer += seprintf(buffer, last, " [%02i] %*p %-40s + 0x%zx\n", i, int(2 + sizeof(void*) * 2),
trace[i], info.dli_fname, (char *)trace[i] - (char *)info.dli_fbase);
continue;
}
#endif
buffer += seprintf(buffer, last, " [%02i] %s\n", i, messages[i]); buffer += seprintf(buffer, last, " [%02i] %s\n", i, messages[i]);
} }
free(messages); free(messages);