Skip to content

Commit

Permalink
Don't try generating a backtrace on stack overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Mar 4, 2022
1 parent 11e065b commit bee530b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 16 deletions.
18 changes: 15 additions & 3 deletions lib/vm/src/trap/traphandlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,16 +715,28 @@ impl<T> TrapHandlerContextInner<T> {
return false;
}

// Set up the register state for exception return to force the
// coroutine to return to its caller with UnwindReason::WasmTrap.
let backtrace = Backtrace::new_unresolved();
let signal_trap = maybe_fault_address.map(|addr| {
if self.coro_trap_handler.stack_ptr_in_bounds(addr) {
TrapCode::StackOverflow
} else {
TrapCode::HeapAccessOutOfBounds
}
});

// Don't try to generate a backtrace for stack overflows: unwinding
// information is often not precise enough to properly describe what is
// happenning during a function prologue, which can lead the unwinder to
// read invalid memory addresses.
//
// See: https://github.com/rust-lang/backtrace-rs/pull/357
let backtrace = if signal_trap == Some(TrapCode::StackOverflow) {
Backtrace::from(vec![])
} else {
Backtrace::new_unresolved()
};

// Set up the register state for exception return to force the
// coroutine to return to its caller with UnwindReason::WasmTrap.
let unwind = UnwindReason::WasmTrap {
backtrace,
signal_trap,
Expand Down
10 changes: 3 additions & 7 deletions tests/compilers/traps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,9 @@ fn test_trap_stack_overflow(config: crate::Config) -> Result<()> {

let e = run_func.call(&[]).err().expect("error calling function");

let trace = e.trace();
assert!(trace.len() >= 32);
for i in 0..trace.len() {
assert_eq!(trace[i].module_name(), "rec_mod");
assert_eq!(trace[i].func_index(), 0);
assert_eq!(trace[i].function_name(), Some("run"));
}
// We specifically don't check the stack trace here: stack traces after
// stack overflows are not generally possible due to unreliable unwinding
// information.
assert!(e.message().contains("call stack exhausted"));

Ok(())
Expand Down
6 changes: 0 additions & 6 deletions tests/ignores.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,10 @@ aarch64 traps::start_trap_pretty
singlepass multi_value_imports::dylib # Singlepass doesn't support multivalue
singlepass multi_value_imports::dynamic # Singlepass doesn't support multivalue

# TODO: We need to fix this in ARM. The issue is caused by libunwind overflowing
# the stack while creating the stacktrace.
# https://github.com/rust-lang/backtrace-rs/issues/356
# Also neither LLVM nor Cranelift currently implement stack probing on AArch64.
# https://github.com/wasmerio/wasmer/issues/2808
cranelift+aarch64 spec::skip_stack_guard_page
llvm+aarch64 spec::skip_stack_guard_page
# TODO: Needs more investigation
cranelift+macos spec::skip_stack_guard_page
llvm+macos spec::skip_stack_guard_page

# Some SIMD opperations are not yet supported by Cranelift
# Cranelift just added support for most of those recently, it might be easy to update
Expand Down

0 comments on commit bee530b

Please sign in to comment.