Fix the stacks fuzzer in the face of stack overflow (#4557)
When the `stacks` fuzzer hits a stack overflow the trace generated by Wasmtime will have one more frame than the trace generated by the wasm itself. This comes about due to the wasm not actually pushing the final frame when it stack overflows. The host, however, will still see the final frame that triggered the stack overflow. In this situation the fuzzer asserts that the host has one extra frame and then discards the frame.
This commit is contained in:
@@ -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<TrapCode>,
|
||||
) {
|
||||
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: {:?}",
|
||||
|
||||
Reference in New Issue
Block a user