From 475b2cc3be25e8c69c9f178b0d6835845a65b0a3 Mon Sep 17 00:00:00 2001 From: Owen Shepherd Date: Wed, 15 Aug 2012 23:53:54 +0100 Subject: [PATCH] win32: add a last chance exception handler which invokes the appropriate signal handler --- platform/win32/crt0.c | 58 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/platform/win32/crt0.c b/platform/win32/crt0.c index fcdee08..f7f6a92 100644 --- a/platform/win32/crt0.c +++ b/platform/win32/crt0.c @@ -2,6 +2,7 @@ #include #include #include +#include static char ** argvToAnsi( wchar_t ** wargv, int argc ) { @@ -40,6 +41,60 @@ static void freeArgs( void ) LocalFree( wargv ); } +extern void (*_PDCLIB_sigfpe)( int ); +extern void (*_PDCLIB_sigill)( int ); +extern void (*_PDCLIB_sigsegv)( int ); + +static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; +static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo ) +{ + int sig; + void (*handler)( int ); + + switch( exInfo->ExceptionRecord->ExceptionCode ) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_GUARD_PAGE: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_STACK_OVERFLOW: + sig = SIGSEGV; + handler = _PDCLIB_sigsegv; + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_PRIV_INSTRUCTION: + sig = SIGILL; + handler = _PDCLIB_sigill; + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: + sig = SIGFPE; + handler = _PDCLIB_sigfpe; + break; + + default: + return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER; + } + + if(handler == SIG_DFL) { + return EXCEPTION_EXECUTE_HANDLER; + } else if(handler == SIG_IGN) { + return EXCEPTION_CONTINUE_EXECUTION; + } else { + handler( sig ); + return EXCEPTION_CONTINUE_EXECUTION; + } +} + extern int main( int argc, char ** argv, char ** envp ); _PDCLIB_noreturn void mainCRTStartup( void ) { @@ -47,11 +102,14 @@ _PDCLIB_noreturn void mainCRTStartup( void ) stdout->handle = GetStdHandle(STD_OUTPUT_HANDLE); stderr->handle = GetStdHandle(STD_ERROR_HANDLE); + oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter ); + cl = GetCommandLineW(); wargv = CommandLineToArgvW(cl, &argc); argv = argvToAnsi(wargv, argc); atexit(freeArgs); int exitStatus = main(argc, argv, NULL); + exit(exitStatus); } -- 2.40.0