GC panics while tracing a suspended stack-switching continuation

Open Beginner friendly
#14,239 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust, wasm
Domain
backend

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.

Description

wasm-proposal:gc wasm-proposal:stack-switching
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:

#[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
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
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 16h
Merged PRs (30d)
107

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from bytecodealliance/wasmtime

All issues in bytecodealliance/wasmtime

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.