Skip to content

Commit 704c783

Browse files
bors[bot]Henrik Rydgårdsyrusakbaryxmclark
committed
Merge #414
414: Exception logging (win32): Handle error codes correctly, add some more strings r=syrusakbary a=hrydgard Ran into a situation with an unknown exception from Cranelift (will probably report that one separately). Turns out the signum was "1" though which does not seem to correspond to any of the Windows error codes, except possibly STATUS_GUARD_PAGE which is 0x80000001, but only if we lost the top bit somewhere. On Windows, exceptions seemed to be trapped by callProtected, which is implemented here: https://github.com/wasmerio/wasmer/blob/cade9a666f5dfedfc9352718988aa26f21b028f4/lib/win-exception-handler/exception_handling/exception_handling.c . It did not seem to correctly store and retrieve the exception code, instead always returning 1: ```longjmp(jmpBuf, 1);``` So I fixed it. And now the log output looks like this: ``` unhandled trap at 1560d5e7bab - code #c0000005: segmentation violation ``` Co-authored-by: Henrik Rydgård <[email protected]> Co-authored-by: Syrus Akbary <[email protected]> Co-authored-by: Mackenzie Clark <[email protected]>
2 parents f292687 + 10b4a08 commit 704c783

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

lib/clif-backend/src/signal/unix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub fn call_protected<T>(
107107
Ok(SIGSEGV) => "segmentation violation",
108108
Ok(SIGBUS) => "bus error",
109109
Err(_) => "error while getting the Signal",
110-
_ => "unkown trapped signal",
110+
_ => "unknown trapped signal",
111111
};
112112
// When the trap-handler is fully implemented, this will return more information.
113113
let s = format!("unknown trap at {:p} - {}", faulting_addr, signal);

lib/clif-backend/src/signal/windows.rs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ use crate::trampoline::Trampoline;
44
use std::cell::Cell;
55
use std::ffi::c_void;
66
use std::ptr::{self, NonNull};
7-
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
87
use wasmer_runtime_core::typed_func::WasmTrapInfo;
98
use wasmer_runtime_core::vm::Ctx;
109
use wasmer_runtime_core::vm::Func;
1110
use wasmer_win_exception_handler::CallProtectedData;
1211
pub use wasmer_win_exception_handler::_call_protected;
1312
use winapi::shared::minwindef::DWORD;
1413
use winapi::um::minwinbase::{
15-
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
14+
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_BREAKPOINT,
15+
EXCEPTION_DATATYPE_MISALIGNMENT, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
1616
EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
17-
EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION,
18-
EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_STACK_OVERFLOW,
17+
EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_GUARD_PAGE,
18+
EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW,
19+
EXCEPTION_INVALID_HANDLE, EXCEPTION_IN_PAGE_ERROR, EXCEPTION_NONCONTINUABLE_EXCEPTION,
20+
EXCEPTION_POSSIBLE_DEADLOCK, EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_SINGLE_STEP,
21+
EXCEPTION_STACK_OVERFLOW,
1922
};
2023

2124
thread_local! {
@@ -43,7 +46,7 @@ pub fn call_protected(
4346
}
4447

4548
let CallProtectedData {
46-
code: signum,
49+
code,
4750
exception_address,
4851
instruction_pointer,
4952
} = result.unwrap_err();
@@ -53,7 +56,7 @@ pub fn call_protected(
5356
srcloc: _,
5457
}) = handler_data.lookup(instruction_pointer as _)
5558
{
56-
Err(CallProtError::Trap(match signum as DWORD {
59+
Err(CallProtError::Trap(match code as DWORD {
5760
EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds,
5861
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
5962
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
@@ -70,7 +73,7 @@ pub fn call_protected(
7073
_ => WasmTrapInfo::Unknown,
7174
}))
7275
} else {
73-
let signal = match signum as DWORD {
76+
let signal = match code as DWORD {
7477
EXCEPTION_FLT_DENORMAL_OPERAND
7578
| EXCEPTION_FLT_DIVIDE_BY_ZERO
7679
| EXCEPTION_FLT_INEXACT_RESULT
@@ -80,10 +83,26 @@ pub fn call_protected(
8083
| EXCEPTION_FLT_UNDERFLOW => "floating-point exception",
8184
EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction",
8285
EXCEPTION_ACCESS_VIOLATION => "segmentation violation",
83-
_ => "unkown trapped signal",
86+
EXCEPTION_DATATYPE_MISALIGNMENT => "datatype misalignment",
87+
EXCEPTION_BREAKPOINT => "breakpoint",
88+
EXCEPTION_SINGLE_STEP => "single step",
89+
EXCEPTION_ARRAY_BOUNDS_EXCEEDED => "array bounds exceeded",
90+
EXCEPTION_INT_DIVIDE_BY_ZERO => "int div by zero",
91+
EXCEPTION_INT_OVERFLOW => "int overflow",
92+
EXCEPTION_PRIV_INSTRUCTION => "priv instruction",
93+
EXCEPTION_IN_PAGE_ERROR => "in page error",
94+
EXCEPTION_NONCONTINUABLE_EXCEPTION => "non continuable exception",
95+
EXCEPTION_STACK_OVERFLOW => "stack overflow",
96+
EXCEPTION_GUARD_PAGE => "guard page",
97+
EXCEPTION_INVALID_HANDLE => "invalid handle",
98+
EXCEPTION_POSSIBLE_DEADLOCK => "possible deadlock",
99+
_ => "unknown exception code",
84100
};
85101

86-
let s = format!("unknown trap at {} - {}", exception_address, signal);
102+
let s = format!(
103+
"unhandled trap at {:x} - code #{:x}: {}",
104+
exception_address, code, signal,
105+
);
87106

88107
Err(CallProtError::Error(Box::new(s)))
89108
}

lib/singlepass-backend/src/protect_unix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub fn call_protected<T>(f: impl FnOnce() -> T) -> Result<T, CallProtError> {
111111
// Ok(SIGSEGV) => "segmentation violation",
112112
// Ok(SIGBUS) => "bus error",
113113
// Err(_) => "error while getting the Signal",
114-
// _ => "unkown trapped signal",
114+
// _ => "unknown trapped signal",
115115
// };
116116
// // When the trap-handler is fully implemented, this will return more information.
117117
// Err(RuntimeError::Trap {

lib/win-exception-handler/exception_handling/exception_handling.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define CALL_FIRST 1
66

77
__declspec(thread) jmp_buf jmpBuf;
8+
__declspec(thread) DWORD caughtExceptionCode;
89
__declspec(thread) PVOID caughtExceptionAddress;
910
__declspec(thread) DWORD64 caughtInstructionPointer;
1011
__declspec(thread) PVOID savedStackPointer;
@@ -25,6 +26,7 @@ static LONG WINAPI
2526
exceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
2627
EXCEPTION_RECORD* pExceptionRecord = ExceptionInfo->ExceptionRecord;
2728
PCONTEXT pCONTEXT = ExceptionInfo->ContextRecord;
29+
caughtExceptionCode = pExceptionRecord->ExceptionCode;
2830
caughtExceptionAddress = pExceptionRecord->ExceptionAddress;
2931
caughtInstructionPointer = pCONTEXT->Rip;
3032
if (alreadyHandlingException == TRUE) {
@@ -61,8 +63,9 @@ uint8_t callProtected(trampoline_t trampoline,
6163
}
6264

6365
// jmp jmp jmp!
64-
int signum = setjmp(jmpBuf);
65-
if (signum == 0) {
66+
int status = setjmp(jmpBuf);
67+
if (status == 0) // 0 means the original call
68+
{
6669
// save the stack pointer
6770
savedStackPointer = get_callee_frame_address();
6871
trampoline(ctx, func, param_vec, return_vec);
@@ -74,7 +77,7 @@ uint8_t callProtected(trampoline_t trampoline,
7477
return TRUE;
7578
}
7679

77-
out_result->code = (uint64_t)signum;
80+
out_result->code = (uint64_t)caughtExceptionCode;
7881
out_result->exception_address = (uint64_t)caughtExceptionAddress;
7982
out_result->instruction_pointer = caughtInstructionPointer;
8083

@@ -83,4 +86,4 @@ uint8_t callProtected(trampoline_t trampoline,
8386

8487
removeExceptionHandler();
8588
return FALSE;
86-
}
89+
}

0 commit comments

Comments
 (0)