Index: src/gnuwin32/sys-win32.c =================================================================== --- src/gnuwin32/sys-win32.c (revision 86850) +++ src/gnuwin32/sys-win32.c (working copy) @@ -26,6 +26,8 @@ #include #endif +#include + #include #include #include @@ -384,3 +386,69 @@ return rval; } } + +static WINAPI LONG veh_report_and_raise(PEXCEPTION_POINTERS ei) +{ + int signal = 0; + const char *exception = 0; + switch (ei->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ILLEGAL_INSTRUCTION: + exception = "illegal instruction"; + signal = SIGILL; + break; + case EXCEPTION_ACCESS_VIOLATION: + exception = "access violation"; + signal = SIGSEGV; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + exception = "array bounds overflow"; + signal = SIGSEGV; + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + exception = "datatype misalignment"; + signal = SIGSEGV; + break; + case EXCEPTION_IN_PAGE_ERROR: + exception = "page load failure"; + signal = SIGSEGV; + break; + case EXCEPTION_PRIV_INSTRUCTION: + exception = "privileged instruction"; + signal = SIGILL; + break; + case EXCEPTION_STACK_OVERFLOW: + exception = "stack overflow"; + signal = SIGSEGV; + break; + default: /* do nothing */ ; + } + if (signal) { + REprintf("*** caught %s at program counter %p ***\n", + exception, ei->ExceptionRecord->ExceptionAddress); + /* just two more special cases */ + switch (ei->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_IN_PAGE_ERROR: + { + const char * action; + switch (ei->ExceptionRecord->ExceptionInformation[0]) { + case 0: action = "read"; break; + case 1: action = "write"; break; + case 8: action = "execute"; break; + default: action = ""; + } + REprintf("accessing address %p, action: %s\n", + (void*)ei->ExceptionRecord->ExceptionInformation[1], + action); + break; + } + } + raise(signal); + } + return EXCEPTION_CONTINUE_SEARCH; +} + +void R_setup_veh_segv(void) +{ + (void)AddVectoredExceptionHandler(0, veh_report_and_raise); +} Index: src/main/main.c =================================================================== --- src/main/main.c (revision 86850) +++ src/main/main.c (working copy) @@ -457,8 +457,6 @@ #ifdef Win32 -static int num_caught = 0; - static void win32_segv(int signum) { /* NB: stack overflow is not an access violation on Win32 */ @@ -478,12 +476,6 @@ UNPROTECT(1); } } - num_caught++; - if(num_caught < 10) signal(signum, win32_segv); - if(signum == SIGILL) - error("caught access violation - continue with care"); - else - error("caught access violation - continue with care"); } #endif @@ -707,6 +699,7 @@ #ifndef Win32 signal(SIGPIPE, handlePipe); #else + R_setup_veh_segv(); signal(SIGSEGV, win32_segv); signal(SIGILL, win32_segv); #endif Index: src/include/Defn.h =================================================================== --- src/include/Defn.h (revision 86850) +++ src/include/Defn.h (working copy) @@ -2330,6 +2330,7 @@ void R_wfixbackslash(wchar_t *s); void R_wfixslash(wchar_t *s); wchar_t *filenameToWchar(const SEXP fn, const Rboolean expand); +void R_setup_veh_segv(void); #endif FILE *RC_fopen(const SEXP fn, const char *mode, const Rboolean expand);