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;
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;
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");
Header file for CrashHandler class.
This class is designed to catch exceptions thrown by libc (SIGABRT, SIGSEGV, SIGILL,...
This namespace is the default namespace for all code in the openshot library.