Stream: git-wasmtime

Topic: wasmtime / PR #11717 Continuation trapping semantics


view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 15:24):

dhil requested alexcrichton for a review on PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 15:24):

dhil opened PR #11717 from dhil:continuation-trapping to bytecodealliance:main:

This patch fixes a problem with traps on continuations, which would otherwise allow a Wasm program to continue running after invoking a trapping instruction. Currently, a fresh trap handler is installed per continuation stack, meaning that the effects of a trap is delimited by the stack segment on which the trap occurred -- whereas it really ought to be delimited by the top-level of the program (i.e. the part just before host/engine frames).

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 15:24):

dhil requested wasmtime-core-reviewers for a review on PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 18:19):

posborne submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2025 at 18:19):

posborne created PR review comment:

Should be able to be simplified slightly to just matches!(*stack_chain, VMStackChain::Continuation(_))

view this post on Zulip Wasmtime GitHub notifications bot (Sep 21 2025 at 03:15):

alexcrichton requested fitzgen for a review on PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 21 2025 at 03:16):

alexcrichton commented on PR #11717:

I'm not familiar enough with the stack-switching code currently to review this myself. For example I don't know if this is accidentally skipping over native frames at the base of other continuations. Given that I'm going to defer to @fitzgen and @posborne as they're more familiar with the details

view this post on Zulip Wasmtime GitHub notifications bot (Sep 22 2025 at 15:19):

dhil commented on PR #11717:

For example I don't know if this is accidentally skipping over native frames at the base of other continuations.

Excellent point. I think it may skip over intermediate invoke_wasm_and_catch_traps frames, suggesting that a "bubbling" semantics of trapping up through continuation stacks may be the right thing to do.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 23 2025 at 17:44):

fitzgen submitted PR review:

Thanks for fixing this bug!

Can we add a test that spawns an N deep stack chain with M frames where every other frame is a host frame, and the last frame (whether host or Wasm) triggers a trap? Then we can run that test exhaustively for small N and M.

Something like

(module
  ;; The imported host function.
  (import "host" "func" (func $host_func (param i32 i32)))

  ;; A global that is incremented after calling the host
  ;; function, which should trap, and therefore the
  ;; increment should never happen.
  (global $g (export "g") (mut i32) (i32.const 0))

  (func (export "run") (param $frames-per-stack i32) (param $fuel i32)
    ;; Trap on out-of-fuel for frames.
    if (i32.eqz (local.get $fuel))
      unreachable
    end

    ;; Decrement frame fuel.
    (local.set $fuel (i32.sub (local.get $fuel) (i32.const 1)))

    if (i32.eqz (i32.rem (local.get $fuel) (local.get $frames-per-stack))))
      ;; TODO: Spawn a new stack, starting either with `run`
      ;; or our host function (based on another param or a
      ;; global or something), and switch to it...
    else
      ;; Call the host function to continue our mutual recursion.
      (call $host_func (local.get $frames-per-stack) (local.get $frame-fuel))
    end

    ;; Increment the global. Should never execute, dynamically.
    (global.set $g (i32.add (global.get $g) (i32.const 1))
  )
)
let host_func = Func::wrap(
    &mut store,
    |mut caller: Caller<'_, ()>, frames_per_stack: u32, fuel: u32| -> Result<()> {
        ;; Trap on out-of-fuel for frames.
        if fuel == 0 {
            bail!("out of frame fuel");
        }

        ;; Mutual recursion back into the Wasm function.
        let run = instance.get_typed_func::<(u32, u32)>(&mut caller).unwrap();
        run.call(&mut caller, (frames_per_stack, fuel - 1))?;

        ;; Increment the global. Should never execute, dynamically.
        let g = instance.get_global("g").unwrap();
        let g_val = g.get(&mut caller).unwrap_i32();
        g.set(&mut caller, Val::I32(g_val + 1))?;

        Ok(())
    },
);

// ...

for frames_per_stack in 1..4 {
    for fuel in 0..frames_per_stack * 3 {
        let mut store = Store::new(&engine, ());
        let instance = Instance::new(...)?;

        let run = instance.get_typed_func::<(u32, u32)>(&mut store)?;
        run.call(&mut store, (frames_per_stack, fuel))?;

        let g = instance.get_global(&mut store, "g").unwrap();
        assert_eq!(g.unwrap_i32(), 0);
    }
}

This would give me a lot more confidence that we are properly handling traps across stacks, regardless of the stack chain, host functions, and what kind of frame is youngest or oldest.

(And when we add embedder API support for spawning stacks, we should also extend the host function in this new test to use that support)

view this post on Zulip Wasmtime GitHub notifications bot (Jan 21 2026 at 18:34):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jan 22 2026 at 16:23):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 11:33):

dhil requested cfallin for a review on PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 11:33):

dhil requested wasmtime-compiler-reviewers for a review on PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 11:33):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 11:41):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 13:04):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 13:21):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 13:31):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 13:50):

dhil commented on PR #11717:

@fitzgen PTAL when its convenient -- and apologies for the latency! I have added two new commits:

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 13:55):

dhil edited a comment on PR #11717:

@fitzgen PTAL when its convenient -- and apologies for the latency! I have added two new commits:

If we go with this "bubbling" approach, then I will drop the first two commits of this PR.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 15:39):

:thumbs_up: fitzgen submitted PR review:

Thanks! LGTM with nitpicks below addressed

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 15:39):

:speech_balloon: fitzgen created PR review comment:

And similar here

view this post on Zulip Wasmtime GitHub notifications bot (Jul 23 2026 at 15:39):

:speech_balloon: fitzgen created PR review comment:

Can you define AliasRegions::last_wasm_entry_sp and use it via env.alias_regions.last_wasm_entry_sp here? That will ensure that we are using the correct alias region for this load.

I know it is currently a little tedious, but I plan on tackling https://github.com/bytecodealliance/wasmtime/issues/13707 soon, which should remove all the boilerplate.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 11:26):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 15:44):

:memo: dhil submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 15:44):

:speech_balloon: dhil created PR review comment:

Yes! That's an oversight from me. I have added them in https://github.com/bytecodealliance/wasmtime/pull/11717/commits/71b933fef854120bb859ff4700c5fe7205dc3e6c.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 15:50):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 15:51):

:speech_balloon: dhil edited PR review comment.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 16:59):

:thumbs_up: fitzgen submitted PR review:

Thanks!

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 16:59):

fitzgen added PR #11717 Continuation trapping semantics to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 17:24):

github-merge-queue[bot] removed PR #11717 Continuation trapping semantics from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 24 2026 at 18:05):

fitzgen commented on PR #11717:

@dhil I think you need to mark the new tests as #[cfg_attr(miri, ignore)], since they run Wasm and MIRI can't handle that, except in very limited cases.

https://github.com/bytecodealliance/wasmtime/actions/runs/30111260793/job/89541246907#step:6:654

view this post on Zulip Wasmtime GitHub notifications bot (Jul 25 2026 at 10:59):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 25 2026 at 11:00):

dhil commented on PR #11717:

@dhil I think you need to mark the new tests as #[cfg_attr(miri, ignore)], since they run Wasm and MIRI can't handle that, except in very limited cases.

https://github.com/bytecodealliance/wasmtime/actions/runs/30111260793/job/89541246907#step:6:654

I've added the directive to the continuation trap tests in commit https://github.com/bytecodealliance/wasmtime/pull/11717/commits/ec6cf0b17afcaa6adc3f9fd50c596c5dde6725f6.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 15:59):

:thumbs_up: fitzgen submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 15:59):

fitzgen added PR #11717 Continuation trapping semantics to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 16:47):

github-merge-queue[bot] removed PR #11717 Continuation trapping semantics from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 17:04):

dhil commented on PR #11717:

@fitzgen looks like the merge queue failed on Test macOS arm64 (wasmtime) -- I am not sure how it is related to this PR, are there more conditional compilation directives that I need to add?

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 19:08):

fitzgen added PR #11717 Continuation trapping semantics to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 19:09):

fitzgen commented on PR #11717:

I re-enqueued to see if that was some flaky test, but I'm not aware of any flaky segfaults (that would be pretty concerning) so I suspect that the segfault is related to this PR

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 19:46):

github-merge-queue[bot] removed PR #11717 Continuation trapping semantics from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 19:49):

alexcrichton added PR #11717 Continuation trapping semantics to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 27 2026 at 21:44):

github-merge-queue[bot] removed PR #11717 Continuation trapping semantics from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 08:26):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 09:58):

dhil updated PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 11:11):

dhil commented on PR #11717:

@fitzgen The continuation trapping tests were failing with ASAN build. I have added ignore(asan) directives to the two tests too. We need to instrument the stack switching runtime with asan markers in a similar way to the async fiber runtime. Though, I prefer to defer this to a subsequent patch.

There is a wasi-nn test that keeps failing, but I see it failed on main during the night too https://github.com/bytecodealliance/wasmtime/actions/runs/30326568601/job/90173165029 -- I suppose this failure is unrelated to this PR.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 14:26):

alexcrichton added PR #11717 Continuation trapping semantics to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 14:27):

alexcrichton commented on PR #11717:

Yeah wasi-nn is no longer gated on right now while it's flaky

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 14:52):

:check: alexcrichton merged PR #11717.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 28 2026 at 14:52):

alexcrichton removed PR #11717 Continuation trapping semantics from the merge queue.


Last updated: Jul 29 2026 at 05:03 UTC