mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
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:
parent
500a47bc2f
commit
cd672e251f
7 changed files with 169 additions and 88 deletions
|
@ -11,20 +11,20 @@
|
|||
#
|
||||
ifeq ($(MODE),)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
TARGET_ARCH ?= -msse3
|
||||
endif
|
||||
ifeq ($(MODE), x86_64)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
ifeq ($(MODE), aarch64)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += -O2 $(BACKTRACES)
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
|
@ -38,13 +38,13 @@ endif
|
|||
#
|
||||
ifeq ($(MODE), zero)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0
|
||||
OVERRIDE_CXXFLAGS += -O0
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
endif
|
||||
ifeq ($(MODE), aarch64-zero)
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
OVERRIDE_CFLAGS += -O0 -fdce
|
||||
OVERRIDE_CXXFLAGS += -O0 -fdce
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG
|
||||
|
@ -81,7 +81,7 @@ endif
|
|||
#
|
||||
ifeq ($(MODE), opt)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O3 -fmerge-all-constants
|
||||
TARGET_ARCH ?= -march=native
|
||||
|
@ -98,7 +98,7 @@ endif
|
|||
# - Turns off support for other operating systems
|
||||
#
|
||||
ifeq ($(MODE), optlinux)
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||
CONFIG_COPTS += -mred-zone
|
||||
|
@ -140,7 +140,7 @@ endif
|
|||
#
|
||||
ifeq ($(MODE), asan)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -D__SANITIZE_ADDRESS__
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2 -DSYSDEBUG
|
||||
CONFIG_COPTS += -fsanitize=address
|
||||
|
@ -160,7 +160,7 @@ endif
|
|||
#
|
||||
ifeq ($(MODE), dbg)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_ADDRESS__ -D__SANITIZE_UNDEFINED__
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline
|
||||
CONFIG_COPTS += -fsanitize=address -fsanitize=undefined
|
||||
|
@ -170,7 +170,7 @@ QUOTA ?= -C64 -L300
|
|||
endif
|
||||
ifeq ($(MODE), aarch64-dbg)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CPPFLAGS += -DMODE_DBG -D__SANITIZE_UNDEFINED__
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O0 -fno-inline -fdce
|
||||
CONFIG_COPTS += -fsanitize=undefined
|
||||
|
@ -189,7 +189,7 @@ endif
|
|||
#
|
||||
ifeq ($(MODE), sysv)
|
||||
ENABLE_FTRACE = 1
|
||||
CONFIG_OFLAGS ?= -g
|
||||
CONFIG_OFLAGS ?= -g -ggdb
|
||||
CONFIG_CCFLAGS += $(BACKTRACES) -O2
|
||||
CONFIG_CPPFLAGS += -DSYSDEBUG -DSUPPORT_VECTOR=121
|
||||
TARGET_ARCH ?= -msse3
|
||||
|
|
|
@ -147,6 +147,13 @@ o/$(MODE)/libc/calls/pledge-linux.o: private \
|
|||
-fPIC \
|
||||
-ffreestanding
|
||||
|
||||
# we want -Os because:
|
||||
# it makes a big difference
|
||||
# it gets called very rarely
|
||||
o/$(MODE)/libc/calls/sigcrashsig.o: private \
|
||||
CFLAGS += \
|
||||
-Os
|
||||
|
||||
# these assembly files are safe to build on aarch64
|
||||
o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
|
102
libc/calls/sig.c
102
libc/calls/sig.c
|
@ -301,7 +301,7 @@ static textwindows wontreturn void __sig_tramp(struct SignalFrame *sf) {
|
|||
}
|
||||
|
||||
// sends signal to another specific thread which is ref'd
|
||||
static int __sig_killer(struct PosixThread *pt, int sig, int sic) {
|
||||
static textwindows int __sig_killer(struct PosixThread *pt, int sig, int sic) {
|
||||
unsigned rva = __sighandrvas[sig];
|
||||
unsigned flags = __sighandflags[sig];
|
||||
|
||||
|
@ -462,66 +462,7 @@ textwindows void __sig_generate(int sig, int sic) {
|
|||
ALLOW_SIGNALS;
|
||||
}
|
||||
|
||||
static int __sig_crash_sig(struct NtExceptionPointers *ep, int *code) {
|
||||
switch (ep->ExceptionRecord->ExceptionCode) {
|
||||
case kNtSignalBreakpoint:
|
||||
*code = TRAP_BRKPT;
|
||||
return SIGTRAP;
|
||||
case kNtSignalIllegalInstruction:
|
||||
*code = ILL_ILLOPC;
|
||||
return SIGILL;
|
||||
case kNtSignalPrivInstruction:
|
||||
*code = ILL_PRVOPC;
|
||||
return SIGILL;
|
||||
case kNtSignalInPageError:
|
||||
case kNtStatusStackOverflow:
|
||||
*code = SEGV_MAPERR;
|
||||
return SIGSEGV;
|
||||
case kNtSignalGuardPage:
|
||||
case kNtSignalAccessViolation:
|
||||
*code = SEGV_ACCERR;
|
||||
return SIGSEGV;
|
||||
case kNtSignalInvalidHandle:
|
||||
case kNtSignalInvalidParameter:
|
||||
case kNtSignalAssertionFailure:
|
||||
*code = SI_USER;
|
||||
return SIGABRT;
|
||||
case kNtStatusIntegerOverflow:
|
||||
*code = FPE_INTOVF;
|
||||
return SIGFPE;
|
||||
case kNtSignalFltDivideByZero:
|
||||
*code = FPE_FLTDIV;
|
||||
return SIGFPE;
|
||||
case kNtSignalFltOverflow:
|
||||
*code = FPE_FLTOVF;
|
||||
return SIGFPE;
|
||||
case kNtSignalFltUnderflow:
|
||||
*code = FPE_FLTUND;
|
||||
return SIGFPE;
|
||||
case kNtSignalFltInexactResult:
|
||||
*code = FPE_FLTRES;
|
||||
return SIGFPE;
|
||||
case kNtSignalFltDenormalOperand:
|
||||
case kNtSignalFltInvalidOperation:
|
||||
case kNtSignalFltStackCheck:
|
||||
case kNtSignalIntegerDivideByZero:
|
||||
case kNtSignalFloatMultipleFaults:
|
||||
case kNtSignalFloatMultipleTraps:
|
||||
*code = FPE_FLTINV;
|
||||
return SIGFPE;
|
||||
case kNtSignalDllNotFound:
|
||||
case kNtSignalOrdinalNotFound:
|
||||
case kNtSignalEntrypointNotFound:
|
||||
case kNtSignalDllInitFailed:
|
||||
*code = SI_KERNEL;
|
||||
return SIGSYS;
|
||||
default:
|
||||
*code = ep->ExceptionRecord->ExceptionCode;
|
||||
return SIGSEGV;
|
||||
}
|
||||
}
|
||||
|
||||
static char *__sig_stpcpy(char *d, const char *s) {
|
||||
static textwindows char *__sig_stpcpy(char *d, const char *s) {
|
||||
size_t i;
|
||||
for (i = 0;; ++i) {
|
||||
if (!(d[i] = s[i])) {
|
||||
|
@ -530,8 +471,24 @@ static char *__sig_stpcpy(char *d, const char *s) {
|
|||
}
|
||||
}
|
||||
|
||||
static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
|
||||
struct CosmoTib *tib) {
|
||||
static textwindows wontreturn void __sig_death(int sig, const char *thing) {
|
||||
#ifndef TINY
|
||||
intptr_t hStderr;
|
||||
char sigbuf[21], s[128], *p;
|
||||
hStderr = GetStdHandle(kNtStdErrorHandle);
|
||||
p = __sig_stpcpy(s, "Terminating on ");
|
||||
p = __sig_stpcpy(p, thing);
|
||||
p = __sig_stpcpy(p, strsignal_r(sig, sigbuf));
|
||||
p = __sig_stpcpy(p,
|
||||
". Pass --strace and/or ShowCrashReports() for details.\n");
|
||||
WriteFile(hStderr, s, p - s, 0, 0);
|
||||
#endif
|
||||
__sig_terminate(sig);
|
||||
}
|
||||
|
||||
static textwindows void __sig_unmaskable(struct NtExceptionPointers *ep,
|
||||
int code, int sig,
|
||||
struct CosmoTib *tib) {
|
||||
|
||||
// log vital crash information reliably for --strace before doing much
|
||||
// we don't print this without the flag since raw numbers scare people
|
||||
|
@ -549,17 +506,7 @@ static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
|
|||
// exception, then print a friendly helpful hint message to stderr
|
||||
unsigned rva = __sighandrvas[sig];
|
||||
if (rva == (intptr_t)SIG_DFL || rva == (intptr_t)SIG_IGN) {
|
||||
#ifndef TINY
|
||||
intptr_t hStderr;
|
||||
char sigbuf[21], s[128], *p;
|
||||
hStderr = GetStdHandle(kNtStdErrorHandle);
|
||||
p = __sig_stpcpy(s, "Terminating on uncaught ");
|
||||
p = __sig_stpcpy(p, strsignal_r(sig, sigbuf));
|
||||
p = __sig_stpcpy(
|
||||
p, ". Pass --strace and/or ShowCrashReports() for details.\n");
|
||||
WriteFile(hStderr, s, p - s, 0, 0);
|
||||
#endif
|
||||
__sig_terminate(sig);
|
||||
__sig_death(sig, "uncaught ");
|
||||
}
|
||||
|
||||
// if this signal handler is configured to auto-reset to the default
|
||||
|
@ -580,8 +527,9 @@ static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
|
|||
}
|
||||
|
||||
// call the user signal handler
|
||||
// with a temporarily replaced signal mask
|
||||
// and a modifiable view of the faulting code's cpu state
|
||||
// temporarily replace signal mask while calling crash handler
|
||||
// abort process if sig is already blocked to avoid crash loop
|
||||
// note ucontext_t is a hefty data structures on top of NtContext
|
||||
ucontext_t ctx = {0};
|
||||
siginfo_t si = {.si_signo = sig, .si_code = code, .si_addr = si_addr};
|
||||
|
@ -591,6 +539,10 @@ static void __sig_unmaskable(struct NtExceptionPointers *ep, int code, int sig,
|
|||
blocksigs |= 1ull << (sig - 1);
|
||||
ctx.uc_sigmask = atomic_fetch_or_explicit(&tib->tib_sigmask, blocksigs,
|
||||
memory_order_acquire);
|
||||
if (ctx.uc_sigmask & (1ull << (sig - 1))) {
|
||||
__sig_death(sig, "masked ");
|
||||
__sig_terminate(sig);
|
||||
}
|
||||
__sig_handler(rva)(sig, &si, &ctx);
|
||||
atomic_store_explicit(&tib->tib_sigmask, ctx.uc_sigmask,
|
||||
memory_order_release);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/nt/struct/ntexceptionpointers.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
|
||||
#define SIG_HANDLED_NO_RESTART 1
|
||||
|
@ -17,11 +18,12 @@ extern struct Signals __sig;
|
|||
|
||||
bool __sig_ignored(int);
|
||||
int __sig_check(void);
|
||||
int __sig_crash_sig(struct NtExceptionPointers *, int *);
|
||||
int __sig_get(sigset_t);
|
||||
int __sig_kill(struct PosixThread *, int, int);
|
||||
int __sig_mask(int, const sigset_t *, sigset_t *);
|
||||
int __sig_relay(int, int, sigset_t);
|
||||
int __sig_raise(int, int);
|
||||
int __sig_get(sigset_t);
|
||||
int __sig_relay(int, int, sigset_t);
|
||||
void __sig_delete(int);
|
||||
void __sig_generate(int, int);
|
||||
void __sig_init(void);
|
||||
|
|
107
libc/calls/sigcrashsig.c
Normal file
107
libc/calls/sigcrashsig.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2024 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/intrin/pushpop.internal.h"
|
||||
#include "libc/nt/enum/signal.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/struct/ntexceptionpointers.h"
|
||||
|
||||
// this is all a mandatory dependency of winmain
|
||||
// so, we trade away maintanibility for tininess
|
||||
// see libc/sysv/consts.sh for canonical magnums
|
||||
|
||||
#define SIGILL_ pushpop(4)
|
||||
#define SIGTRAP_ pushpop(5)
|
||||
#define SIGABRT_ pushpop(6)
|
||||
#define SIGFPE_ pushpop(8)
|
||||
#define SIGSEGV_ pushpop(11)
|
||||
#define SIGSYS_ pushpop(31)
|
||||
|
||||
#define TRAP_BRKPT_ pushpop(1)
|
||||
#define ILL_ILLOPC_ pushpop(1)
|
||||
#define ILL_PRVOPC_ pushpop(5)
|
||||
#define SEGV_MAPERR_ pushpop(1)
|
||||
#define SEGV_ACCERR_ pushpop(2)
|
||||
#define SI_USER_ pushpop(0)
|
||||
#define FPE_FLTDIV_ pushpop(3)
|
||||
#define FPE_FLTOVF_ pushpop(4)
|
||||
#define FPE_INTOVF_ pushpop(2)
|
||||
#define FPE_FLTUND_ pushpop(5)
|
||||
#define FPE_FLTRES_ pushpop(6)
|
||||
#define FPE_FLTINV_ pushpop(7)
|
||||
#define SI_KERNEL_ 0x80
|
||||
|
||||
textwindows int __sig_crash_sig(struct NtExceptionPointers *ep, int *code) {
|
||||
switch (ep->ExceptionRecord->ExceptionCode) {
|
||||
case kNtSignalBreakpoint:
|
||||
*code = TRAP_BRKPT_;
|
||||
return SIGTRAP_;
|
||||
case kNtSignalIllegalInstruction:
|
||||
*code = ILL_ILLOPC_;
|
||||
return SIGILL_;
|
||||
case kNtSignalPrivInstruction:
|
||||
*code = ILL_PRVOPC_;
|
||||
return SIGILL_;
|
||||
case kNtSignalInPageError:
|
||||
case kNtStatusStackOverflow:
|
||||
*code = SEGV_MAPERR_;
|
||||
return SIGSEGV_;
|
||||
case kNtSignalGuardPage:
|
||||
case kNtSignalAccessViolation:
|
||||
*code = SEGV_ACCERR_;
|
||||
return SIGSEGV_;
|
||||
case kNtSignalInvalidHandle:
|
||||
case kNtSignalInvalidParameter:
|
||||
case kNtSignalAssertionFailure:
|
||||
*code = SI_USER_;
|
||||
return SIGABRT_;
|
||||
case kNtStatusIntegerOverflow:
|
||||
*code = FPE_INTOVF_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalFltDivideByZero:
|
||||
*code = FPE_FLTDIV_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalFltOverflow:
|
||||
*code = FPE_FLTOVF_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalFltUnderflow:
|
||||
*code = FPE_FLTUND_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalFltInexactResult:
|
||||
*code = FPE_FLTRES_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalFltDenormalOperand:
|
||||
case kNtSignalFltInvalidOperation:
|
||||
case kNtSignalFltStackCheck:
|
||||
case kNtSignalIntegerDivideByZero:
|
||||
case kNtSignalFloatMultipleFaults:
|
||||
case kNtSignalFloatMultipleTraps:
|
||||
*code = FPE_FLTINV_;
|
||||
return SIGFPE_;
|
||||
case kNtSignalDllNotFound:
|
||||
case kNtSignalOrdinalNotFound:
|
||||
case kNtSignalEntrypointNotFound:
|
||||
case kNtSignalDllInitFailed:
|
||||
*code = SI_KERNEL_;
|
||||
return SIGSYS_;
|
||||
default:
|
||||
*code = ep->ExceptionRecord->ExceptionCode;
|
||||
return SIGSEGV_;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -512,6 +512,8 @@ syscon compat SA_ONESHOT 0x80000000 0x80000000 4 4 4 4 4 0x800000
|
|||
# The New Technology NT is polyfilled as Linux.
|
||||
# Unsupported values are encoded as 0x80000000.
|
||||
#
|
||||
# NOTE: Some of these Windows constants are duplicated in sigcrashsig.c
|
||||
#
|
||||
# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary
|
||||
syscon sicode SI_USER 0 0 0x010001 0x010001 0x010001 0 0 0 # sent by kill(2); openbsd defines si_code<=0 as originating from user
|
||||
syscon sicode SI_QUEUE -1 -1 0x010002 0x010002 0x010002 -2 -1 -1 # sent by sigqueue(2)
|
||||
|
|
Loading…
Reference in a new issue