28 #include "../include/CrashHandler.h" 46 signal(SIGSEGV, CrashHandler::abortHandler);
50 sa.sa_flags = SA_SIGINFO;
51 sa.sa_sigaction = CrashHandler::abortHandler;
52 sigemptyset( &sa.sa_mask );
55 sigaction( SIGABRT, &sa, NULL );
56 sigaction( SIGSEGV, &sa, NULL );
57 sigaction( SIGBUS, &sa, NULL );
58 sigaction( SIGILL, &sa, NULL );
59 sigaction( SIGFPE, &sa, NULL );
60 sigaction( SIGPIPE, &sa, NULL );
69 void CrashHandler::abortHandler(
int signum)
72 const char* name = NULL;
75 case SIGABRT: name =
"SIGABRT";
break;
76 case SIGSEGV: name =
"SIGSEGV";
break;
77 case SIGILL: name =
"SIGILL";
break;
78 case SIGFPE: name =
"SIGFPE";
break;
83 fprintf( stderr,
"Caught signal %d (%s)\n", signum, name );
85 fprintf( stderr,
"Caught signal %d\n", signum );
88 printStackTrace(stderr, 63);
95 void CrashHandler::abortHandler(
int signum, siginfo_t* si,
void* unused )
98 const char* name = NULL;
101 case SIGABRT: name =
"SIGABRT";
break;
102 case SIGSEGV: name =
"SIGSEGV";
break;
103 case SIGBUS: name =
"SIGBUS";
break;
104 case SIGILL: name =
"SIGILL";
break;
105 case SIGFPE: name =
"SIGFPE";
break;
106 case SIGPIPE: name =
"SIGPIPE";
break;
111 fprintf( stderr,
"Caught signal %d (%s)\n", signum, name );
113 fprintf( stderr,
"Caught signal %d\n", signum );
116 printStackTrace(stderr, 63);
123 void CrashHandler::printStackTrace(FILE *out,
unsigned int max_frames)
125 fprintf(out,
"---- Unhandled Exception: Stack Trace ----\n");
126 ZmqLogger::Instance()->LogToFile(
"---- Unhandled Exception: Stack Trace ----\n");
127 stringstream stack_output;
131 HANDLE process = GetCurrentProcess();
132 HANDLE thread = GetCurrentThread();
135 memset(&context, 0,
sizeof(CONTEXT));
136 context.ContextFlags = CONTEXT_FULL;
137 RtlCaptureContext(&context);
139 SymInitialize(process, NULL, TRUE);
142 STACKFRAME64 stackframe;
143 ZeroMemory(&stackframe,
sizeof(STACKFRAME64));
146 image = IMAGE_FILE_MACHINE_I386;
147 stackframe.AddrPC.Offset = context.Eip;
148 stackframe.AddrPC.Mode = AddrModeFlat;
149 stackframe.AddrFrame.Offset = context.Ebp;
150 stackframe.AddrFrame.Mode = AddrModeFlat;
151 stackframe.AddrStack.Offset = context.Esp;
152 stackframe.AddrStack.Mode = AddrModeFlat;
154 image = IMAGE_FILE_MACHINE_AMD64;
155 stackframe.AddrPC.Offset = context.Rip;
156 stackframe.AddrPC.Mode = AddrModeFlat;
157 stackframe.AddrFrame.Offset = context.Rsp;
158 stackframe.AddrFrame.Mode = AddrModeFlat;
159 stackframe.AddrStack.Offset = context.Rsp;
160 stackframe.AddrStack.Mode = AddrModeFlat;
162 image = IMAGE_FILE_MACHINE_IA64;
163 stackframe.AddrPC.Offset = context.StIIP;
164 stackframe.AddrPC.Mode = AddrModeFlat;
165 stackframe.AddrFrame.Offset = context.IntSp;
166 stackframe.AddrFrame.Mode = AddrModeFlat;
167 stackframe.AddrBStore.Offset = context.RsBSP;
168 stackframe.AddrBStore.Mode = AddrModeFlat;
169 stackframe.AddrStack.Offset = context.IntSp;
170 stackframe.AddrStack.Mode = AddrModeFlat;
174 for (
size_t i = 0; i < max_frames; i++) {
176 BOOL result = StackWalk64(
177 image, process, thread,
178 &stackframe, &context, NULL,
179 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
181 if (i <= 2) {
continue; }
182 if (!result) {
break; }
184 char buffer[
sizeof(SYMBOL_INFO) + MAX_SYM_NAME *
sizeof(TCHAR)];
185 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
186 symbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
187 symbol->MaxNameLen = MAX_SYM_NAME;
188 WINBOOL found_symbol = SymFromAddr(process, stackframe.AddrPC.Offset, NULL, symbol);
191 printf(
"[%i] %s, address 0x%0X\n", i, symbol->Name, symbol->Address);
192 stack_output << left << setw(30) << symbol->Name <<
" " << setw(40) << std::hex << symbol->Address << std::dec << endl;
194 printf(
"[%i] ???\n", i);
195 stack_output << left << setw(30) <<
"???" << endl;
203 void* addrlist[max_frames+1];
206 unsigned int addrlen = backtrace( addrlist,
sizeof( addrlist ) /
sizeof(
void* ));
210 fprintf(out,
" No stack trace found (addrlen == 0)\n");
211 ZmqLogger::Instance()->LogToFile(
" No stack trace found (addrlen == 0)\n");
218 char** symbollist = backtrace_symbols( addrlist, addrlen );
220 size_t funcnamesize = 1024;
225 for (
unsigned int i = 4; i < addrlen; i++ )
227 char* begin_name = NULL;
228 char* begin_offset = NULL;
229 char* end_offset = NULL;
234 for (
char *p = symbollist[i]; *p; ++p )
236 if (( *p ==
'_' ) && ( *(p-1) ==
' ' ))
238 else if ( *p ==
'+' )
242 if ( begin_name && begin_offset && ( begin_name < begin_offset ))
244 *begin_name++ =
'\0';
245 *begin_offset++ =
'\0';
251 char* ret = abi::__cxa_demangle( begin_name, &funcname[0], &funcnamesize, &status );
255 fprintf( out,
" %-30s %-40s %s\n", symbollist[i], funcname, begin_offset );
256 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << funcname <<
" " << begin_offset << endl;
260 fprintf( out,
" %-30s %-38s() %s\n", symbollist[i], begin_name, begin_offset );
261 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(38) << begin_name <<
" " << begin_offset << endl;
264 #else // !DARWIN - but is posix 267 for (
char *p = symbollist[i]; *p; ++p )
271 else if ( *p ==
'+' )
273 else if ( *p ==
')' && ( begin_offset || begin_name ))
277 if ( begin_name && end_offset && ( begin_name < end_offset ))
279 *begin_name++ =
'\0';
280 *end_offset++ =
'\0';
282 *begin_offset++ =
'\0';
288 char* ret = abi::__cxa_demangle( begin_name, funcname, &funcnamesize, &status );
289 char* fname = begin_name;
295 fprintf( out,
" %-30s ( %-40s + %-6s) %s\n", symbollist[i], fname, begin_offset, end_offset );
296 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << fname <<
" " << begin_offset <<
" " << end_offset << endl;
299 fprintf( out,
" %-30s ( %-40s %-6s) %s\n", symbollist[i], fname,
"", end_offset );
300 stack_output << left <<
" " << setw(30) << symbollist[i] <<
" " << setw(40) << fname <<
" " << end_offset << endl;
303 #endif // !DARWIN - but is posix 306 fprintf(out,
" %-40s\n", symbollist[i]);
307 stack_output << left <<
" " << setw(40) << symbollist[i] << endl;
316 ZmqLogger::Instance()->LogToFile(stack_output.str());
318 fprintf(out,
"---- End of Stack Trace ----\n");
319 ZmqLogger::Instance()->LogToFile(
"---- End of Stack Trace ----\n");
This class is designed to catch exceptions thrown by libc (SIGABRT, SIGSEGV, SIGILL, SIGFPE)
This namespace is the default namespace for all code in the openshot library.