23 #if !defined(WIN32) && defined(CRASH_HANDLER)
37 #define MAX_BACKTRACE_DEPTH 128
38 #define DEMANGLE_BACKTRACE_SYMBOLS
40 void crashHandler(
int signum, siginfo_t* info,
void* secret)
52 ss.flags(std::ios::hex | std::ios::showbase);
54 ucontext_t context = *(ucontext_t*)secret;
56 ss <<
" at rip = " << context.uc_mcontext.gregs[REG_RIP] << std::endl;
57 ss <<
" rax = " << context.uc_mcontext.gregs[REG_RAX] << std::endl;
58 ss <<
" rbx = " << context.uc_mcontext.gregs[REG_RBX] << std::endl;
59 ss <<
" rcx = " << context.uc_mcontext.gregs[REG_RCX] << std::endl;
60 ss <<
" rdx = " << context.uc_mcontext.gregs[REG_RDX] << std::endl;
61 ss <<
" rsi = " << context.uc_mcontext.gregs[REG_RSI] << std::endl;
62 ss <<
" rdi = " << context.uc_mcontext.gregs[REG_RDI] << std::endl;
63 ss <<
" rbp = " << context.uc_mcontext.gregs[REG_RBP] << std::endl;
64 ss <<
" rsp = " << context.uc_mcontext.gregs[REG_RSP] << std::endl;
65 ss <<
" efl = " << context.uc_mcontext.gregs[REG_EFL] << std::endl;
67 #elif defined(REG_EIP)
68 ss <<
" at eip = " << context.uc_mcontext.gregs[REG_EIP] << std::endl;
69 ss <<
" eax = " << context.uc_mcontext.gregs[REG_EAX] << std::endl;
70 ss <<
" ebx = " << context.uc_mcontext.gregs[REG_EBX] << std::endl;
71 ss <<
" ecx = " << context.uc_mcontext.gregs[REG_ECX] << std::endl;
72 ss <<
" edx = " << context.uc_mcontext.gregs[REG_EDX] << std::endl;
73 ss <<
" esi = " << context.uc_mcontext.gregs[REG_ESI] << std::endl;
74 ss <<
" edi = " << context.uc_mcontext.gregs[REG_EDI] << std::endl;
75 ss <<
" ebp = " << context.uc_mcontext.gregs[REG_EBP] << std::endl;
76 ss <<
" esp = " << context.uc_mcontext.gregs[REG_ESP] << std::endl;
77 ss <<
" efl = " << context.uc_mcontext.gregs[REG_EFL] << std::endl;
81 ss.flags(std::ios::dec);
82 ss <<
" backtrace:" << std::endl;
84 void* buffer[MAX_BACKTRACE_DEPTH];
85 int numLevels = backtrace(buffer, MAX_BACKTRACE_DEPTH);
86 char **tracebackBuffer = backtrace_symbols(buffer, numLevels);
88 for(
int i = 2; i < numLevels; i++) {
89 std::string line = tracebackBuffer[i];
90 if(line.find(
"__libc_start_main") != std::string::npos)
92 #ifdef DEMANGLE_BACKTRACE_SYMBOLS
93 std::size_t demanglePos = line.find(
"(_Z");
94 if(demanglePos != std::string::npos) {
96 int len = std::min(line.find_first_of(
"+", demanglePos), line.find_first_of(
")", demanglePos)) - demanglePos;
97 std::string funcName = line.substr(demanglePos, len);
101 ss <<
" " << i-1 <<
": " << line << std::endl;
103 free(tracebackBuffer);
108 std::string fileName =
"crash_report.log";
109 std::ofstream fout(fileName.c_str(), std::ios::out | std::ios::app);
110 if(fout.is_open() && fout.good()) {
111 fout <<
"== application crashed\n";
119 signal(SIGILL, SIG_DFL);
120 signal(SIGSEGV, SIG_DFL);
121 signal(SIGFPE, SIG_DFL);
122 signal(SIGABRT, SIG_DFL);
125 void installCrashHandler()
128 sa.sa_sigaction = &crashHandler;
129 sigemptyset (&sa.sa_mask);
130 sa.sa_flags = SA_RESTART | SA_SIGINFO;
132 sigaction(SIGILL, &sa,
nullptr);
133 sigaction(SIGSEGV, &sa,
nullptr);
134 sigaction(SIGFPE, &sa,
nullptr);
135 sigaction(SIGABRT, &sa,
nullptr);