diff --git a/crates/fuzzing/src/oracles/stacks.rs b/crates/fuzzing/src/oracles/stacks.rs index 3a289a97f9..54dde5801f 100644 --- a/crates/fuzzing/src/oracles/stacks.rs +++ b/crates/fuzzing/src/oracles/stacks.rs @@ -57,7 +57,9 @@ pub fn check_stacks(stacks: Stacks) -> usize { let mut max_stack_depth = 0; for input in stacks.inputs().iter().copied() { + log::debug!("input: {}", input); if let Err(trap) = run.call(&mut store, (input.into(),)) { + log::debug!("trap: {}", trap); let get_stack = instance .get_typed_func::<(), (u32, u32), _>(&mut store, "get_stack") .expect("should export `get_stack` function as expected"); @@ -72,7 +74,7 @@ pub fn check_stacks(stacks: Stacks) -> usize { let host_trace = trap.trace().unwrap(); max_stack_depth = max_stack_depth.max(host_trace.len()); - assert_stack_matches(&mut store, memory, ptr, len, host_trace); + assert_stack_matches(&mut store, memory, ptr, len, host_trace, trap.trap_code()); } } max_stack_depth @@ -85,6 +87,7 @@ fn assert_stack_matches( ptr: u32, len: u32, host_trace: &[FrameInfo], + trap_code: Option, ) { let mut data = vec![0; len as usize]; memory @@ -99,6 +102,19 @@ fn assert_stack_matches( wasm_trace.push(entry); } + // If the test case here trapped due to stack overflow then the host trace + // will have one more frame than the wasm trace. The wasm didn't actually + // get to the point of pushing onto its own trace stack where the host will + // be able to see the exact function that triggered the stack overflow. In + // this situation the host trace is asserted to be one larger and then the + // top frame (first) of the host trace is discarded. + let host_trace = if trap_code == Some(TrapCode::StackOverflow) { + assert_eq!(host_trace.len(), wasm_trace.len() + 1); + &host_trace[1..] + } else { + host_trace + }; + log::debug!("Wasm thinks its stack is: {:?}", wasm_trace); log::debug!( "Host thinks the stack is: {:?}",