Exception logging (win32): Handle error codes correctly, add some more strings.

This commit is contained in:
Henrik Rydgård
2019-05-02 11:09:57 +02:00
parent 6c567924c2
commit 5e37368ec9
4 changed files with 37 additions and 15 deletions

View File

@ -107,7 +107,7 @@ pub fn call_protected<T>(
Ok(SIGSEGV) => "segmentation violation", Ok(SIGSEGV) => "segmentation violation",
Ok(SIGBUS) => "bus error", Ok(SIGBUS) => "bus error",
Err(_) => "error while getting the Signal", Err(_) => "error while getting the Signal",
_ => "unkown trapped signal", _ => "unknown trapped signal",
}; };
// When the trap-handler is fully implemented, this will return more information. // When the trap-handler is fully implemented, this will return more information.
let s = format!("unknown trap at {:p} - {}", faulting_addr, signal); let s = format!("unknown trap at {:p} - {}", faulting_addr, signal);

View File

@ -4,7 +4,6 @@ use crate::trampoline::Trampoline;
use std::cell::Cell; use std::cell::Cell;
use std::ffi::c_void; use std::ffi::c_void;
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
use wasmer_runtime_core::typed_func::WasmTrapInfo; use wasmer_runtime_core::typed_func::WasmTrapInfo;
use wasmer_runtime_core::vm::Ctx; use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::vm::Func; use wasmer_runtime_core::vm::Func;
@ -12,10 +11,14 @@ use wasmer_win_exception_handler::CallProtectedData;
pub use wasmer_win_exception_handler::_call_protected; pub use wasmer_win_exception_handler::_call_protected;
use winapi::shared::minwindef::DWORD; use winapi::shared::minwindef::DWORD;
use winapi::um::minwinbase::{ use winapi::um::minwinbase::{
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO, EXCEPTION_ACCESS_VIOLATION, EXCEPTION_ARRAY_BOUNDS_EXCEEDED, EXCEPTION_BREAKPOINT,
EXCEPTION_DATATYPE_MISALIGNMENT, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW, EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_GUARD_PAGE,
EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_STACK_OVERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION, EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW,
EXCEPTION_INVALID_HANDLE, EXCEPTION_IN_PAGE_ERROR, EXCEPTION_NONCONTINUABLE_EXCEPTION,
EXCEPTION_POSSIBLE_DEADLOCK, EXCEPTION_PRIV_INSTRUCTION, EXCEPTION_SINGLE_STEP,
EXCEPTION_STACK_OVERFLOW,
}; };
thread_local! { thread_local! {
@ -43,7 +46,7 @@ pub fn call_protected(
} }
let CallProtectedData { let CallProtectedData {
code: signum, code,
exception_address, exception_address,
instruction_pointer, instruction_pointer,
} = result.unwrap_err(); } = result.unwrap_err();
@ -53,7 +56,7 @@ pub fn call_protected(
srcloc: _, srcloc: _,
}) = handler_data.lookup(instruction_pointer as _) }) = handler_data.lookup(instruction_pointer as _)
{ {
Err(CallProtError::Trap(match signum as DWORD { Err(CallProtError::Trap(match code as DWORD {
EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds, EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds,
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode { EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature, TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
@ -70,7 +73,7 @@ pub fn call_protected(
_ => WasmTrapInfo::Unknown, _ => WasmTrapInfo::Unknown,
})) }))
} else { } else {
let signal = match signum as DWORD { let signal = match code as DWORD {
EXCEPTION_FLT_DENORMAL_OPERAND EXCEPTION_FLT_DENORMAL_OPERAND
| EXCEPTION_FLT_DIVIDE_BY_ZERO | EXCEPTION_FLT_DIVIDE_BY_ZERO
| EXCEPTION_FLT_INEXACT_RESULT | EXCEPTION_FLT_INEXACT_RESULT
@ -80,10 +83,26 @@ pub fn call_protected(
| EXCEPTION_FLT_UNDERFLOW => "floating-point exception", | EXCEPTION_FLT_UNDERFLOW => "floating-point exception",
EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction", EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction",
EXCEPTION_ACCESS_VIOLATION => "segmentation violation", EXCEPTION_ACCESS_VIOLATION => "segmentation violation",
_ => "unkown trapped signal", EXCEPTION_DATATYPE_MISALIGNMENT => "datatype misalignment",
EXCEPTION_BREAKPOINT => "breakpoint",
EXCEPTION_SINGLE_STEP => "single step",
EXCEPTION_ARRAY_BOUNDS_EXCEEDED => "array bounds exceeded",
EXCEPTION_INT_DIVIDE_BY_ZERO => "int div by zero",
EXCEPTION_INT_OVERFLOW => "int overflow",
EXCEPTION_PRIV_INSTRUCTION => "priv instruction",
EXCEPTION_IN_PAGE_ERROR => "in page error",
EXCEPTION_NONCONTINUABLE_EXCEPTION => "non continuable exception",
EXCEPTION_STACK_OVERFLOW => "stack overflow",
EXCEPTION_GUARD_PAGE => "guard page",
EXCEPTION_INVALID_HANDLE => "invalid handle",
EXCEPTION_POSSIBLE_DEADLOCK => "possible deadlock",
_ => "unknown exception code",
}; };
let s = format!("unknown trap at {} - {}", exception_address, signal); let s = format!(
"unhandled trap at {:x} - code #{:x}: {}",
exception_address, code, signal,
);
Err(CallProtError::Error(Box::new(s))) Err(CallProtError::Error(Box::new(s)))
} }

View File

@ -111,7 +111,7 @@ pub fn call_protected<T>(f: impl FnOnce() -> T) -> Result<T, CallProtError> {
// Ok(SIGSEGV) => "segmentation violation", // Ok(SIGSEGV) => "segmentation violation",
// Ok(SIGBUS) => "bus error", // Ok(SIGBUS) => "bus error",
// Err(_) => "error while getting the Signal", // Err(_) => "error while getting the Signal",
// _ => "unkown trapped signal", // _ => "unknown trapped signal",
// }; // };
// // When the trap-handler is fully implemented, this will return more information. // // When the trap-handler is fully implemented, this will return more information.
// Err(RuntimeError::Trap { // Err(RuntimeError::Trap {

View File

@ -5,6 +5,7 @@
#define CALL_FIRST 1 #define CALL_FIRST 1
__declspec(thread) jmp_buf jmpBuf; __declspec(thread) jmp_buf jmpBuf;
__declspec(thread) DWORD caughtExceptionCode;
__declspec(thread) PVOID caughtExceptionAddress; __declspec(thread) PVOID caughtExceptionAddress;
__declspec(thread) DWORD64 caughtInstructionPointer; __declspec(thread) DWORD64 caughtInstructionPointer;
__declspec(thread) PVOID savedStackPointer; __declspec(thread) PVOID savedStackPointer;
@ -25,6 +26,7 @@ static LONG WINAPI
exceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) { exceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo) {
EXCEPTION_RECORD* pExceptionRecord = ExceptionInfo->ExceptionRecord; EXCEPTION_RECORD* pExceptionRecord = ExceptionInfo->ExceptionRecord;
PCONTEXT pCONTEXT = ExceptionInfo->ContextRecord; PCONTEXT pCONTEXT = ExceptionInfo->ContextRecord;
caughtExceptionCode = pExceptionRecord->ExceptionCode;
caughtExceptionAddress = pExceptionRecord->ExceptionAddress; caughtExceptionAddress = pExceptionRecord->ExceptionAddress;
caughtInstructionPointer = pCONTEXT->Rip; caughtInstructionPointer = pCONTEXT->Rip;
if (alreadyHandlingException == TRUE) { if (alreadyHandlingException == TRUE) {
@ -61,8 +63,9 @@ uint8_t callProtected(trampoline_t trampoline,
} }
// jmp jmp jmp! // jmp jmp jmp!
int signum = setjmp(jmpBuf); int status = setjmp(jmpBuf);
if (signum == 0) { if (status == 0) // 0 means the original call
{
// save the stack pointer // save the stack pointer
savedStackPointer = get_callee_frame_address(); savedStackPointer = get_callee_frame_address();
trampoline(ctx, func, param_vec, return_vec); trampoline(ctx, func, param_vec, return_vec);
@ -74,7 +77,7 @@ uint8_t callProtected(trampoline_t trampoline,
return TRUE; return TRUE;
} }
out_result->code = (uint64_t)signum; out_result->code = (uint64_t)caughtExceptionCode;
out_result->exception_address = (uint64_t)caughtExceptionAddress; out_result->exception_address = (uint64_t)caughtExceptionAddress;
out_result->instruction_pointer = caughtInstructionPointer; out_result->instruction_pointer = caughtInstructionPointer;