mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-28 16:11:32 +00:00
Exception logging (win32): Handle error codes correctly, add some more strings.
This commit is contained in:
@ -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);
|
||||||
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user