35 signal(SIGSEGV, CrashHandler::abortHandler);
39 sa.sa_flags = SA_SIGINFO;
40 sa.sa_sigaction = CrashHandler::abortHandler;
41 sigemptyset( &sa.sa_mask );
44 sigaction( SIGABRT, &sa, NULL );
45 sigaction( SIGSEGV, &sa, NULL );
46 sigaction( SIGBUS, &sa, NULL );
47 sigaction( SIGILL, &sa, NULL );
48 sigaction( SIGFPE, &sa, NULL );
49 sigaction( SIGPIPE, &sa, NULL );
58 void CrashHandler::abortHandler(
int signum)
61 const char* name = NULL;
64 case SIGABRT: name =
"SIGABRT";
break;
65 case SIGSEGV: name =
"SIGSEGV";
break;
66 case SIGILL: name =
"SIGILL";
break;
67 case SIGFPE: name =
"SIGFPE";
break;
72 fprintf( stderr,
"Caught signal %d (%s)\n", signum, name );
74 fprintf( stderr,
"Caught signal %d\n", signum );
77 printStackTrace(stderr, 63);
84 void CrashHandler::abortHandler(
int signum, siginfo_t* si,
void* unused )
87 const char* name = NULL;
90 case SIGABRT: name =
"SIGABRT";
break;
91 case SIGSEGV: name =
"SIGSEGV";
break;
92 case SIGBUS: name =
"SIGBUS";
break;
93 case SIGILL: name =
"SIGILL";
break;
94 case SIGFPE: name =
"SIGFPE";
break;
95 case SIGPIPE: name =
"SIGPIPE";
break;
100 fprintf( stderr,
"Caught signal %d (%s)\n", signum, name );
102 fprintf( stderr,
"Caught signal %d\n", signum );
105 printStackTrace(stderr, 63);
112 void CrashHandler::printStackTrace(FILE *out,
unsigned int max_frames)
114 fprintf(out,
"---- Unhandled Exception: Stack Trace ----\n");
115 ZmqLogger::Instance()->LogToFile(
"---- Unhandled Exception: Stack Trace ----\n");
116 stringstream stack_output;
120 HANDLE process = GetCurrentProcess();
121 HANDLE thread = GetCurrentThread();
124 memset(&context, 0,
sizeof(CONTEXT));
125 context.ContextFlags = CONTEXT_FULL;
126 RtlCaptureContext(&context);
128 SymInitialize(process, NULL, TRUE);
131 STACKFRAME64 stackframe;
132 ZeroMemory(&stackframe,
sizeof(STACKFRAME64));
135 image = IMAGE_FILE_MACHINE_I386;
136 stackframe.AddrPC.Offset = context.Eip;
137 stackframe.AddrPC.Mode = AddrModeFlat;
138 stackframe.AddrFrame.Offset = context.Ebp;
139 stackframe.AddrFrame.Mode = AddrModeFlat;
140 stackframe.AddrStack.Offset = context.Esp;
141 stackframe.AddrStack.Mode = AddrModeFlat;
143 image = IMAGE_FILE_MACHINE_AMD64;
144 stackframe.AddrPC.Offset = context.Rip;
145 stackframe.AddrPC.Mode = AddrModeFlat;
146 stackframe.AddrFrame.Offset = context.Rsp;
147 stackframe.AddrFrame.Mode = AddrModeFlat;
148 stackframe.AddrStack.Offset = context.Rsp;
149 stackframe.AddrStack.Mode = AddrModeFlat;
151 image = IMAGE_FILE_MACHINE_IA64;
152 stackframe.AddrPC.Offset = context.StIIP;
153 stackframe.AddrPC.Mode = AddrModeFlat;
154 stackframe.AddrFrame.Offset = context.IntSp;
155 stackframe.AddrFrame.Mode = AddrModeFlat;
156 stackframe.AddrBStore.Offset = context.RsBSP;
157 stackframe.AddrBStore.Mode = AddrModeFlat;
158 stackframe.AddrStack.Offset = context.IntSp;
159 stackframe.AddrStack.Mode = AddrModeFlat;
163 for (
size_t i = 0; i < max_frames; i++) {
165 BOOL result = StackWalk64(
166 image, process, thread,
167 &stackframe, &context, NULL,
168 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
170 if (i <= 2) {
continue; }
171 if (!result) {
break; }
173 char buffer[
sizeof(SYMBOL_INFO) + MAX_SYM_NAME *
sizeof(TCHAR)];
174 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
175 symbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
176 symbol->MaxNameLen = MAX_SYM_NAME;
177 WINBOOL found_symbol = SymFromAddr(process, stackframe.AddrPC.Offset, NULL, symbol);
180 printf(
"[%i] %s, address 0x%0X\n", i, symbol->Name, symbol->Address);
181 stack_output << left << setw(30) << symbol->Name <<
" " << setw(40) << std::hex << symbol->Address << std::dec << endl;
183 printf(
"[%i] ???\n", i);
184 stack_output << left << setw(30) <<
"???" << endl;
192 void* addrlist[max_frames+1];
195 unsigned int addrlen = backtrace( addrlist,
sizeof( addrlist ) /
sizeof(
void* ));
199 fprintf(out,
" No stack trace found (addrlen == 0)\n");
200 ZmqLogger::Instance()->LogToFile(
" No stack trace found (addrlen == 0)\n");
207 char** symbollist = backtrace_symbols( addrlist, addrlen );
209 size_t funcnamesize = 1024;
214 for (
unsigned int i = 4; i < addrlen; i++ )
216 char* begin_name = NULL;
217 char* begin_offset = NULL;
218 char* end_offset = NULL;
223 for (
char *p = symbollist[i]; *p; ++p )
225 if (( *p ==
'_' ) && ( *(p-1) ==
' ' ))
227 else if ( *p ==
'+' )
231 if ( begin_name && begin_offset && ( begin_name < begin_offset ))
233 *begin_name++ =
'\0';
234 *begin_offset++ =
'\0';
240 char* ret = abi::__cxa_demangle( begin_name, &funcname[0], &funcnamesize, &status );
244 fprintf( out,
" %-30s %-40s %s\n", symbollist[i], funcname, begin_offset );
245 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << funcname <<
" " << begin_offset << endl;
249 fprintf( out,
" %-30s %-38s() %s\n", symbollist[i], begin_name, begin_offset );
250 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(38) << begin_name <<
" " << begin_offset << endl;
253 #else // !DARWIN - but is posix
256 for (
char *p = symbollist[i]; *p; ++p )
260 else if ( *p ==
'+' )
262 else if ( *p ==
')' && ( begin_offset || begin_name ))
266 if ( begin_name && end_offset && ( begin_name < end_offset ))
268 *begin_name++ =
'\0';
269 *end_offset++ =
'\0';
271 *begin_offset++ =
'\0';
277 char* ret = abi::__cxa_demangle( begin_name, funcname, &funcnamesize, &status );
278 char* fname = begin_name;
284 fprintf( out,
" %-30s ( %-40s + %-6s) %s\n", symbollist[i], fname, begin_offset, end_offset );
285 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << fname <<
" " << begin_offset <<
" " << end_offset << endl;
288 fprintf( out,
" %-30s ( %-40s %-6s) %s\n", symbollist[i], fname,
"", end_offset );
289 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << fname <<
" " << end_offset << endl;
292 #endif // !DARWIN - but is posix
295 fprintf(out,
" %-40s\n", symbollist[i]);
296 stack_output << left <<
" " << setw(40) << symbollist[i] << endl;
305 ZmqLogger::Instance()->LogToFile(stack_output.str());
307 fprintf(out,
"---- End of Stack Trace ----\n");
308 ZmqLogger::Instance()->LogToFile(
"---- End of Stack Trace ----\n");