Hello R-devel, When checking packages on Windows, a crash of the process looks like a sudden stop in the output of the child process, which can be very perplexing for package maintainers (e.g. [1,2]), especially if the stars are only right on Win-Builder but not on the maintainer's PC. On Unix-like systems, we get a loud message from the SIGSEGV handler and (if we're lucky and the memory manager is still mostly intact) an R-level traceback. A similar signal handler, win32_segv(), is defined in src/main.c for use on Windows, but I am not seeing a way it could be called in the current codebase. The file src/gnuwin32/psignal.c that's responsible for signals on Windows handles Ctrl+C but does not emit SIGSEGV or SIGILL. Can we make use of vectored exception handling [3] to globally catch unhandled exceptions in the Win32 process and transform them into raise(SIGSEGV)? One potential source of problems is threading. The normal Unix-like sigactionSegv(...) doesn't care; if a non-main thread causes a crash with SIGSEGV unblocked, it will run in that thread's context and call R API from there. On Windows, where a simple REprintf() may go into a GUI window, the crash handler may be written in a more cautious manner: - Only set up the crash handler in Rterm, because this is mostly for the benefit of the people reading the R CMD check output - Compare GetCurrentThreadId() against a saved value and don't call R_Traceback() if it doesn't match - Rewrite win32_segv in terms of StringCcbPrintf to static storage and WriteFile(GetStdHandle(STD_ERROR_HANDLE), ...), which may be too much Attached is a crude first draft to see if the approach is viable. If it turns out to be a good idea, I can add the Rterm or thread ID checks, a reentrancy guard, declare and export a special struct win32_segvinfo from psignal.c, put all the crash reporting in win32_segv(), and move the VEH setup into psignal.c's signal(). (Just don't want to waste the effort if this proves ill-advised.) Without the patch: User at WIN-LGTSPJA3F1V MSYS /c/R/R-svn/src/gnuwin32 $ cat crash.c void crash(void) { *(double*)42 = 42; } User at WIN-LGTSPJA3F1V MSYS /c/R/R-svn/src/gnuwin32 $ ../../bin/R -q -s -e 'dyn.load("crash.dll"); .C("crash")' Segmentation fault # <-- printed by MSYS2 shell With the patch: User at WIN-LGTSPJA3F1V MSYS /c/R/R-svn/src/gnuwin32 $ ../../bin/R -q -s -e 'dyn.load("crash.dll"); .C("crash")' *** caught access violation at program counter 0x00007ff911c61387 *** accessing address 0x000000000000002a, action: write Traceback: 1: .C("crash") Segmentation fault With the patch applied, I am not seeing changes in make check-devel or package checks for V8. Couldn't test rJava yet. -- Best regards, Ivan [1] https://stat.ethz.ch/pipermail/r-package-devel/2024q2/010919.html [2] https://stat.ethz.ch/pipermail/r-package-devel/2024q2/010872.html [3] https://learn.microsoft.com/en-us/windows/win32/debug/vectored-exception-handling -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: veh-segv.patch URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20240630/b0d8fbd1/attachment.ksh>