Created
February 3, 2018 17:08
-
-
Save zaps166/2648acb6765b623424a4933ff7415740 to your computer and use it in GitHub Desktop.
Display backtrace at runtime
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// "-rdynamic" must be enabled and symbols mustn't be hidden | |
#include <execinfo.h> | |
#include <cxxabi.h> | |
#include <iostream> | |
#include <iterator> | |
#include <cstdlib> | |
#include <cstring> | |
#include <thread> | |
static void displayBacktrace(const char *text, const int traceSize = 8) | |
{ | |
void **trace = new void *[traceSize]; | |
const int realTraceSize = backtrace(trace, traceSize); | |
char **symbols = backtrace_symbols(trace, realTraceSize); | |
if (realTraceSize > 1) | |
{ | |
const auto oldFlags = std::cerr.flags(); | |
std::cerr << "Backtrace "; | |
if (text) | |
std::cerr << text << ' '; | |
std::cerr << "[thread: " << std::hex << "0x" << std::this_thread::get_id() << "]:\n"; | |
std::cerr.flags(oldFlags); | |
} | |
for (int i = 1; i < realTraceSize; ++i) | |
{ | |
bool displayed = false; | |
if (char *symbol = std::strrchr(symbols[i], '(')) | |
{ | |
char *endOfSymbol = std::strchr(symbol += 1, '+'); | |
const size_t mangledSize = endOfSymbol - symbol; | |
if (endOfSymbol && mangledSize > 0) | |
{ | |
char *mangled = new char[mangledSize + 1]; | |
std::strncpy(mangled, symbol, mangledSize); | |
mangled[mangledSize] = '\0'; | |
if (char *demangled = __cxxabiv1::__cxa_demangle(mangled, nullptr, nullptr, nullptr)) | |
{ | |
const int pathLength = symbol - symbols[i]; | |
std::cerr << " "; | |
std::copy(symbols[i], symbols[i] + pathLength, std::ostream_iterator<char>(std::cerr)); | |
std::cerr << demangled << endOfSymbol << '\n'; | |
std::free(demangled); | |
displayed = true; | |
} | |
delete[] mangled; | |
} | |
} | |
if (!displayed) | |
std::cerr << " " << symbols[i] << '\n'; | |
} | |
std::cerr << std::flush; | |
std::free(symbols); | |
delete[] trace; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment