bytecodealliance / bytecodealliance/wasmtime
GC panics while tracing a suspended stack-switching continuation
- Dominant language
- Rust
- Stars
- 18.6k
- Forks
- 1.8k
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 126
Description
### Wasmtime version
This reproduces with Wasmtime 48.0.1 and current `main` at
`d8a0da6d661605713798c1c9c76be5c28e3159ff`.
### Reproduction
With function references, exceptions, stack switching, and GC enabled, the
following test panics when guest allocations trigger GC while a continuation is
suspended:
```rust
#[cfg_attr(any(asan, miri), ignore)]
#[test]
fn gc_traces_a_suspended_continuation() -> Result<()> {
let wat = r#"
(module
(type $ft (func))
(type $ct (cont $ft))
(type $st (struct (field i32)))
(tag $t)
(func $suspend
(suspend $t)
)
(elem declare func $suspend)
(func (export "entry")
(local $continuation (ref null $ct))
(local $i i32)
(block $handler (result (ref $ct))
(resume $ct
(on $t $handler)
(cont.new $ct (ref.func $suspend)))
(return)
)
(local.set $continuation)
(loop $allocate
(drop (struct.new $st (i32.const 7)))
(local.set $i (i32.add (local.get $i) (i32.const 1)))
(br_if $allocate (i32.lt_u (local.get $i) (i32.const 20000)))
)
(resume $ct (local.get $continuation))
)
)
"#;
test_utils::Runner::new().run_test::<()>(wat, &[])
}
```
### Actual result
```text
panicked at crates/wasmtime/src/runtime/vm/traphandlers/backtrace.rs:340:18:
expected one more VMStackLimits than continuations
```
The stack proceeds through `gc_alloc_raw`, `do_gc`,
`trace_wasm_continuation_roots`, `trace_suspended_continuation`, and
`trace_through_continuations`.
### Expected result
GC should trace the suspended continuation and `entry` should complete normally.
### Analysis
`trace_through_continuations` handles the current activation before walking its
ancestors. It advances the stack-limits iterator past that activation, but does
not advance the matching continuation iterator. The remaining iterators
therefore have different lengths.
Advancing `continuations_iter` once before making it peekable aligns it with the
existing stack-limits advance. The test above fails before that change and
passes afterward.
This appears distinct from #13750, which concerns missing stack maps for
continuation payload values. The broader stack-switching tracking issue is
#10248.
### Environment
- OS: Linux x86_64
- Rust: 1.97.1
Contributor guide
Research direction
Start in crates/wasmtime/src/runtime/vm/traphandlers/backtrace.rs and follow trace_through_continuations through trace_suspended_continuation and trace_wasm_continuation_roots. Run the inline gc_traces_a_suspended_continuation reproduction with GC, stack switching, exceptions, and function references enabled; done means the test completes without the VMStackLimits panic and traces the suspended continuation successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100