bytecodealliance / bytecodealliance/wasmtime

GC panics while tracing a suspended stack-switching continuation

Open Beginner friendly
#14,239 1 comment 0 reactions 0 assignees View on GitHub
wasm-proposal:gc wasm-proposal:stack-switching
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.