From 6569a6dceec10c77578184ce68c26e20ba27fa39 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 3 Jun 2016 11:45:38 +0200 Subject: Print a demangled stacktrace --- synchronizer/CMakeLists.txt | 2 +- synchronizer/main.cpp | 55 +++++++++++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 18 deletions(-) (limited to 'synchronizer') diff --git a/synchronizer/CMakeLists.txt b/synchronizer/CMakeLists.txt index 9e9d8d4..88d50d0 100644 --- a/synchronizer/CMakeLists.txt +++ b/synchronizer/CMakeLists.txt @@ -7,6 +7,6 @@ set(sinksynchronizer_SRCS ) add_executable(${PROJECT_NAME} ${sinksynchronizer_SRCS}) -target_link_libraries(${PROJECT_NAME} sink KF5::Async) +target_link_libraries(${PROJECT_NAME} sink KF5::Async dl) qt5_use_modules(${PROJECT_NAME} Widgets Network) install(TARGETS ${PROJECT_NAME} ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) diff --git a/synchronizer/main.cpp b/synchronizer/main.cpp index 14a8250..4e04acb 100644 --- a/synchronizer/main.cpp +++ b/synchronizer/main.cpp @@ -25,6 +25,10 @@ #include #include #include +#include +#include +#include +#include #include "listener.h" #include "log.h" @@ -35,26 +39,43 @@ Listener *listener = nullptr; +//Print a demangled stacktrace void printStacktrace() { - QString s; - void *trace[256]; - int n = backtrace(trace, 256); - if (n) { - char **strings = backtrace_symbols(trace, n); - - s = QLatin1String("[\n"); - - for (int i = 0; i < n; ++i) { - s += QString::number(i) + QLatin1String(": ") + QLatin1String(strings[i]) + QLatin1String("\n"); - } - s += QLatin1String("]\n"); - std::fprintf(stderr, "Backtrace: %s\n", s.toLatin1().data()); - - if (strings) { - free(strings); - } + int skip = 1; + void *callstack[128]; + const int nMaxFrames = sizeof(callstack) / sizeof(callstack[0]); + char buf[1024]; + int nFrames = backtrace(callstack, nMaxFrames); + char **symbols = backtrace_symbols(callstack, nFrames); + + std::ostringstream trace_buf; + for (int i = skip; i < nFrames; i++) { + // printf("%s\n", symbols[i]); + Dl_info info; + if (dladdr(callstack[i], &info) && info.dli_sname) { + char *demangled = NULL; + int status = -1; + if (info.dli_sname[0] == '_') { + demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); + } + snprintf(buf, sizeof(buf), "%-3d %*p %s + %zd\n", + i, int(2 + sizeof(void*) * 2), callstack[i], + status == 0 ? demangled : + info.dli_sname == 0 ? symbols[i] : info.dli_sname, + (char *)callstack[i] - (char *)info.dli_saddr); + free(demangled); + } else { + snprintf(buf, sizeof(buf), "%-3d %*p %s\n", + i, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]); + } + trace_buf << buf; + } + free(symbols); + if (nFrames == nMaxFrames) { + trace_buf << "[truncated]\n"; } + std::cerr << trace_buf.str(); } int sCounter = 0; -- cgit v1.2.3