1717
1818namespace cage
1919{
20+ namespace
21+ {
22+ void printStackTrace (PEXCEPTION_POINTERS ex);
23+ }
24+
2025 namespace privat
2126 {
27+ void crashHandlerPrintThread ()
28+ {
29+ CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " in thread: " + currentThreadName ());
30+ }
31+
32+ void crashHandlerPrintStack ()
33+ {
34+ CONTEXT ctx = {};
35+ RtlCaptureContext (&ctx); // manual context capture
36+ EXCEPTION_RECORD rec = {};
37+ rec.ExceptionCode = 0xDEAD ; // custom marker
38+ EXCEPTION_POINTERS ptrs = {};
39+ ptrs.ContextRecord = &ctx;
40+ ptrs.ExceptionRecord = &rec;
41+ printStackTrace (&ptrs);
42+ }
43+
2244 void crashHandlerThreadInit ()
2345 {
2446 // reserve safe memory on the stack for handling EXCEPTION_STACK_OVERFLOW
@@ -222,10 +244,11 @@ namespace cage
222244 str + symbol->Name ;
223245 }
224246 CAGE_LOG_CONTINUE (SeverityEnum::Info, " crash-handler" , str.value .empty () ? String (" unknown-frame" ) : str);
225- if (++iteration == 50 )
247+ if (++iteration >= 100 )
226248 break ;
227249 }
228250 SymCleanup (process);
251+ CAGE_LOG_CONTINUE (SeverityEnum::Info, " crash-handler" , " " );
229252 }
230253 else
231254 {
@@ -259,7 +282,7 @@ namespace cage
259282 for (uint32 i = 0 ; i < ex->ExceptionRecord ->NumberParameters ; i++)
260283 CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " parameter[" + i + " ]: " + ex->ExceptionRecord ->ExceptionInformation );
261284 }
262- CAGE_LOG (SeverityEnum::Info, " crash-handler " , Stringizer () + " in thread: " + currentThreadName () );
285+ privat::crashHandlerPrintThread ( );
263286 printStackTrace (ex);
264287 }
265288
@@ -276,7 +299,10 @@ namespace cage
276299 {
277300 commonHandler (ex);
278301 if (previousExceptionFilter)
302+ {
303+ CAGE_LOG (SeverityEnum::Info, " crash-handler" , " calling previous handler" );
279304 return previousExceptionFilter (ex);
305+ }
280306 return EXCEPTION_CONTINUE_SEARCH ;
281307 }
282308
@@ -301,37 +327,31 @@ namespace cage
301327 return data;
302328 }
303329
304- _invalid_parameter_handler previousInvalidParameter = nullptr ;
330+ void commonHandler ()
331+ {
332+ privat::crashHandlerPrintThread ();
333+ privat::crashHandlerPrintStack ();
334+ CAGE_LOG (SeverityEnum::Info, " crash-handler" , " calling abort" );
335+ std::abort ();
336+ }
305337
306338 void invalidParameterHandler (const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t pReserved)
307339 {
308340 CAGE_LOG (SeverityEnum::Error, " crash-handler" , " crash handler: invalid parameter" );
309341 CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " expression: " + narrow (expression) + " , function: " + narrow (function));
310- CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " in thread: " + currentThreadName ());
311- detail::debugBreakpoint ();
312- if (previousInvalidParameter)
313- previousInvalidParameter (expression, function, file, line, pReserved);
314- std::terminate ();
342+ commonHandler ();
315343 }
316344
317- _purecall_handler previousPurecall = nullptr ;
318-
319345 void purecallHandler ()
320346 {
321347 CAGE_LOG (SeverityEnum::Error, " crash-handler" , " crash handler: purecall" );
322- CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " in thread: " + currentThreadName ());
323- detail::debugBreakpoint ();
324- if (previousPurecall)
325- previousPurecall ();
326- std::terminate ();
348+ commonHandler ();
327349 }
328350
329351 void sigAbrtHandler (int )
330352 {
331353 CAGE_LOG (SeverityEnum::Error, " crash-handler" , " crash handler: abort signal" );
332- CAGE_LOG (SeverityEnum::Info, " crash-handler" , Stringizer () + " in thread: " + currentThreadName ());
333- detail::debugBreakpoint ();
334- std::terminate ();
354+ commonHandler ();
335355 }
336356
337357 struct SetupHandlersWindows
@@ -347,8 +367,8 @@ namespace cage
347367 previousExceptionFilter = SetUnhandledExceptionFilter (&unhandledHandler);
348368 if (!SetConsoleCtrlHandler (&consoleHandler, TRUE ))
349369 CAGE_THROW_ERROR (SystemError, " SetConsoleCtrlHandler" , GetLastError ());
350- previousInvalidParameter = _set_invalid_parameter_handler (&invalidParameterHandler);
351- previousPurecall = _set_purecall_handler (&purecallHandler);
370+ _set_invalid_parameter_handler (&invalidParameterHandler);
371+ _set_purecall_handler (&purecallHandler);
352372 signal (SIGABRT , &sigAbrtHandler);
353373 }
354374 } setupHandlersWindows;
0 commit comments