Improve crash signal reporting on Windows

This change fixes a bug where exiting a crash signal handler on Windows
after adding the signal to uc_sigmask, but not correcting the CPU state
would cause the signal handler to loop infinitely, causing process hang

Another issue is that very tiny programs, that don't link posix signals
would not have their SIGILL / SIGSEGV / etc. status reported to Cosmo's
bash shell when terminating on crash. That's fixed by a tiny handler in
WinMain() that knows how to map WIN32 crash codes to the POSIX flavors.
This commit is contained in:
Justine Tunney 2024-05-30 13:42:59 -07:00
parent 500a47bc2f
commit cd672e251f
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
7 changed files with 169 additions and 88 deletions

View file

@ -18,6 +18,7 @@
*/
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/nomultics.internal.h"
#include "libc/intrin/weaken.h"
@ -34,6 +35,7 @@
#include "libc/nt/pedef.internal.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/nt/signals.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/memtrack.internal.h"
@ -49,6 +51,7 @@
#define abi __msabi textwindows dontinstrument
// clang-format off
__msabi extern typeof(AddVectoredExceptionHandler) *const __imp_AddVectoredExceptionHandler;
__msabi extern typeof(CreateFileMapping) *const __imp_CreateFileMappingW;
__msabi extern typeof(DuplicateHandle) *const __imp_DuplicateHandle;
__msabi extern typeof(FreeEnvironmentStrings) *const __imp_FreeEnvironmentStringsW;
@ -153,6 +156,11 @@ static bool32 HasEnvironmentVariable(const char16_t *name) {
return __imp_GetEnvironmentVariableW(name, buf, ARRAYLEN(buf));
}
static abi unsigned OnWinCrash(struct NtExceptionPointers *ep) {
int code, sig = __sig_crash_sig(ep, &code);
TerminateThisProcess(sig);
}
// main function of windows init process
// i.e. first process spawned that isn't forked
static abi wontreturn void WinInit(const char16_t *cmdline) {
@ -180,6 +188,9 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
}
}
// so crash signals can be reported to cosmopolitan bash
__imp_AddVectoredExceptionHandler(true, (void *)OnWinCrash);
// allocate memory for stack and argument block
_mmi.p = _mmi.s;
_mmi.n = ARRAYLEN(_mmi.s);