Skip to content

Instantly share code, notes, and snippets.

@zaps166
Created February 3, 2018 17:08
Show Gist options
  • Save zaps166/2648acb6765b623424a4933ff7415740 to your computer and use it in GitHub Desktop.
Save zaps166/2648acb6765b623424a4933ff7415740 to your computer and use it in GitHub Desktop.
Display backtrace at runtime
// "-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