Add tests that trap, and fix handling of SIGFPE on x86.
This commit is contained in:
11
filetests/trap_divbyzero.wat
Normal file
11
filetests/trap_divbyzero.wat
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
(module
|
||||||
|
(func $foo (result i32)
|
||||||
|
i32.const 1
|
||||||
|
i32.const 0
|
||||||
|
i32.div_s
|
||||||
|
)
|
||||||
|
(func $main
|
||||||
|
(drop (call $foo))
|
||||||
|
)
|
||||||
|
(start $main)
|
||||||
|
)
|
||||||
9
filetests/trap_stackoverflow.wat
Normal file
9
filetests/trap_stackoverflow.wat
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
(module
|
||||||
|
(func $foo
|
||||||
|
(call $main)
|
||||||
|
)
|
||||||
|
(func $main
|
||||||
|
(call $foo)
|
||||||
|
)
|
||||||
|
(start $main)
|
||||||
|
)
|
||||||
9
filetests/trap_unreachable.wat
Normal file
9
filetests/trap_unreachable.wat
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
(module
|
||||||
|
(func $foo
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(func $main
|
||||||
|
(call $foo)
|
||||||
|
)
|
||||||
|
(start $main)
|
||||||
|
)
|
||||||
@@ -592,22 +592,17 @@ MachExceptionHandlerThread(void *arg)
|
|||||||
|
|
||||||
#else // If not Windows or Mac, assume Unix
|
#else // If not Windows or Mac, assume Unix
|
||||||
|
|
||||||
#ifdef __mips__
|
static struct sigaction sPrevSIGSEGVHandler;
|
||||||
static const uint32_t kWasmTrapSignal = SIGFPE;
|
|
||||||
#else
|
|
||||||
static const uint32_t kWasmTrapSignal = SIGILL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct sigaction sPrevSEGVHandler;
|
|
||||||
static struct sigaction sPrevSIGBUSHandler;
|
static struct sigaction sPrevSIGBUSHandler;
|
||||||
static struct sigaction sPrevWasmTrapHandler;
|
static struct sigaction sPrevSIGILLHandler;
|
||||||
|
static struct sigaction sPrevSIGFPEHandler;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
WasmTrapHandler(int signum, siginfo_t* info, void* context)
|
WasmTrapHandler(int signum, siginfo_t* info, void* context)
|
||||||
{
|
{
|
||||||
if (!sAlreadyHandlingTrap) {
|
if (!sAlreadyHandlingTrap) {
|
||||||
AutoHandlingTrap aht;
|
AutoHandlingTrap aht;
|
||||||
assert(signum == SIGSEGV || signum == SIGBUS || signum == kWasmTrapSignal);
|
assert(signum == SIGSEGV || signum == SIGBUS || signum == SIGFPE || signum == SIGILL);
|
||||||
if (HandleTrap(static_cast<CONTEXT*>(context))) {
|
if (HandleTrap(static_cast<CONTEXT*>(context))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -615,9 +610,10 @@ WasmTrapHandler(int signum, siginfo_t* info, void* context)
|
|||||||
|
|
||||||
struct sigaction* previousSignal = nullptr;
|
struct sigaction* previousSignal = nullptr;
|
||||||
switch (signum) {
|
switch (signum) {
|
||||||
case SIGSEGV: previousSignal = &sPrevSEGVHandler; break;
|
case SIGSEGV: previousSignal = &sPrevSIGSEGVHandler; break;
|
||||||
case SIGBUS: previousSignal = &sPrevSIGBUSHandler; break;
|
case SIGBUS: previousSignal = &sPrevSIGBUSHandler; break;
|
||||||
case kWasmTrapSignal: previousSignal = &sPrevWasmTrapHandler; break;
|
case SIGFPE: previousSignal = &sPrevSIGFPEHandler; break;
|
||||||
|
case SIGILL: previousSignal = &sPrevSIGILLHandler; break;
|
||||||
}
|
}
|
||||||
assert(previousSignal);
|
assert(previousSignal);
|
||||||
|
|
||||||
@@ -696,8 +692,8 @@ EnsureEagerSignalHandlers()
|
|||||||
faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
faultHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
||||||
faultHandler.sa_sigaction = WasmTrapHandler;
|
faultHandler.sa_sigaction = WasmTrapHandler;
|
||||||
sigemptyset(&faultHandler.sa_mask);
|
sigemptyset(&faultHandler.sa_mask);
|
||||||
if (sigaction(SIGSEGV, &faultHandler, &sPrevSEGVHandler)) {
|
if (sigaction(SIGSEGV, &faultHandler, &sPrevSIGSEGVHandler)) {
|
||||||
perror("unable to install segv handler");
|
perror("unable to install SIGSEGV handler");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,21 +704,36 @@ EnsureEagerSignalHandlers()
|
|||||||
busHandler.sa_sigaction = WasmTrapHandler;
|
busHandler.sa_sigaction = WasmTrapHandler;
|
||||||
sigemptyset(&busHandler.sa_mask);
|
sigemptyset(&busHandler.sa_mask);
|
||||||
if (sigaction(SIGBUS, &busHandler, &sPrevSIGBUSHandler)) {
|
if (sigaction(SIGBUS, &busHandler, &sPrevSIGBUSHandler)) {
|
||||||
perror("unable to install sigbus handler");
|
perror("unable to install SIGBUS handler");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// Install a handler to handle the instructions that are emitted to implement
|
# if !defined(__mips__)
|
||||||
// wasm traps.
|
// Wasm traps for MIPS currently only raise integer overflow fp exception.
|
||||||
struct sigaction trapHandler;
|
struct sigaction illHandler;
|
||||||
trapHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
illHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
||||||
trapHandler.sa_sigaction = WasmTrapHandler;
|
illHandler.sa_sigaction = WasmTrapHandler;
|
||||||
sigemptyset(&trapHandler.sa_mask);
|
sigemptyset(&illHandler.sa_mask);
|
||||||
if (sigaction(kWasmTrapSignal, &trapHandler, &sPrevWasmTrapHandler)) {
|
if (sigaction(SIGILL, &illHandler, &sPrevSIGILLHandler)) {
|
||||||
perror("unable to install wasm trap handler");
|
perror("unable to install wasm SIGILL handler");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
|
||||||
|
// x86 uses SIGFPE to report division by zero, and wasm traps for MIPS
|
||||||
|
// currently raise integer overflow fp exception.
|
||||||
|
struct sigaction fpeHandler;
|
||||||
|
fpeHandler.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
|
||||||
|
fpeHandler.sa_sigaction = WasmTrapHandler;
|
||||||
|
sigemptyset(&fpeHandler.sa_mask);
|
||||||
|
if (sigaction(SIGFPE, &fpeHandler, &sPrevSIGFPEHandler)) {
|
||||||
|
perror("unable to install wasm SIGFPE handler");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user