Last active
August 29, 2016 15:29
-
-
Save heapwolf/26ff79b82e5f310e2d53 to your computer and use it in GitHub Desktop.
a simple zero-touch, header only stack-trace provider for c++
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
#ifndef STACK_TRACE_H | |
#define STACK_TRACE_H | |
#include <iostream> | |
#include <signal.h> | |
#include <string> | |
#include <dlfcn.h> | |
#include <cxxabi.h> | |
#include <regex> | |
#include <execinfo.h> | |
struct Trace { | |
struct sigaction sa; | |
Trace() { | |
using namespace std; | |
auto backtrace_handler = [](int sig) { | |
string white = "\033[1;37m"; | |
string blue = "\033[1;34m"; | |
cout << white << "Error: "; | |
switch (sig) { | |
case SIGSEGV: | |
cout << "Segmentation fault" << endl; | |
break; | |
case SIGFPE: | |
cout << "Floating point exception" << endl; | |
break; | |
case SIGBUS: | |
cout << "An invalid pointer was dereferenced" << endl; | |
break; | |
} | |
void* callstack[128]; | |
size_t size = backtrace(callstack, 128); | |
char** symbols = backtrace_symbols(callstack, size); | |
for (size_t i = 0; i < size; i++) { | |
Dl_info info; | |
int res = dladdr(callstack[i], &info); | |
string s = symbols[i]; | |
int f = s.find_last_of(" + "); | |
s = s.substr(0, f - 2); | |
f = s.find_last_of(" "); | |
s = s.substr(f + 1, s.size()); | |
int status = 0; | |
char* name = abi::__cxa_demangle(s.c_str(), NULL, NULL, &status); | |
if (status == 0 && string(name).find("Trace::Trace()") == string::npos) { | |
cout | |
<< white << " at " << blue << name | |
<< white << " in " << info.dli_fname << endl; | |
} | |
} | |
abort(); | |
}; | |
sa.sa_handler = backtrace_handler; | |
sigemptyset(&sa.sa_mask); | |
sa.sa_flags = SA_RESTART; | |
sigaction(SIGFPE, &sa, NULL); | |
sigaction(SIGSEGV, &sa, NULL); | |
sigaction(SIGBUS, &sa, NULL); | |
} | |
} trace; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In r2land we have our own dwarf parser. it's not as bloated as the dwarfutils or the binutils ones, and it's under LGPL. Feel free to grab it and do whatever you need. We can discuss about changing the license of it if necessary.