Stream: git-wasmtime

Topic: wasmtime / issue #14508 Stack-switching + asan panic


view this post on Zulip Wasmtime GitHub notifications bot (Oct 03 2026 at 00:03):

alexcrichton opened issue #14508:

With this input:

(module
  (type $ft (func))
  (type $ct (cont $ft))
  (tag $t)
  (global $k (mut (ref null $ct)) (ref.null $ct))

  (func $body (suspend $t) (suspend $t))
  (elem declare func $body)

  (func (export "first")
    (block $h (result (ref $ct))
      (resume $ct (on $t $h) (cont.new $ct (ref.func $body)))
      (unreachable))
    (global.set $k))

  (func (export "second")
    (block $h (result (ref $ct))
      (resume $ct (on $t $h) (global.get $k))
      (unreachable))
    (global.set $k))
)
(invoke "first")
(invoke "second")

wasmtime currently panics with ASan enabled:

$ RUSTFLAGS=-Zsanitizer=address cargo +nightly run --target x86_64-unknown-linux-gnu wast ./repro.wast -W stack-switching
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running `/home/alex/code/wasmtime2/target/x86_64-unknown-linux-gnu/debug/wasmtime wast ./repro.wast -W stack-switching`

thread 'main' (712348) panicked at crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:60:14:
ASan requires the destination stack's bounds
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread 'main' (712348) panicked at /rustc/21b707e3f97e0b522ebd2f277a862339625ad83f/library/core/src/panicking.rs:225:5:
panic in a function that cannot unwind
stack backtrace:
   0:     0x5be5d20b2351 - std[f57a5bc8e5fe77fc]::backtrace_rs::backtrace::libunwind::trace
                               at /rustc/21b707e3f97e0b522ebd2f277a862339625ad83f/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
...

cc @dhil

If useful, an LLM report is:

<details>

ASan build: suspend to a host entry stack whose bounds were never recorded aborts

Severity: low. Only -Zsanitizer=address builds (CI "Test ASAN") with tier-3
stack switching.

Root cause

Every resume/suspend/switch in ASan builds calls
asan_start_switch_fiber(fake_stack_save, target_csi), which expects the
target's asan_stack_bottom (crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:56-62).
For the initial (host) stack, bounds are only filled by
fiber_start_complete (asan.rs:89-101) when a fresh continuation is first
entered. Each host->wasm entry gets a new VMCommonStackInformation with
asan_stack_bottom: None (stack_switching.rs:93). Resuming a continuation
started in an earlier entry and then suspending targets the new entry's
stack -> expect panics in an extern "C" fn -> abort.

Repro

repro.wast (first starts a continuation, second resumes it in a new
entry and it suspends). control.wast does both in one entry and passes.

RUSTFLAGS=-Zsanitizer=address CARGO_TARGET_DIR=target/audit-asan \
  cargo +nightly build --release --target x86_64-unknown-linux-gnu -p wasmtime-cli
target/audit-asan/x86_64-unknown-linux-gnu/release/wasmtime wast \
  -W stack-switching=y,exceptions=y,function-references=y repro.wast

Observed:

panicked at crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:60:14:
ASan requires the destination stack's bounds
... panic in a function that cannot unwind
thread caused non-unwinding panic. aborting.

Non-ASan release CLI runs repro.wast fine.

Suggested fix

In finish_switch_fiber, keep the bottom_old/size_old ASan reports
(currently discarded) and store them in the parent stack info, mirroring
fiber_start_complete; or compute host stack bounds on wasm entry
(pthread_getattr_np) and set them in EntryStoreContext::enter_wasm under
cfg(asan).

</details>

view this post on Zulip Wasmtime GitHub notifications bot (Oct 03 2026 at 00:03):

alexcrichton added the wasm-proposal:stack-switching label to Issue #14508.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 07 2026 at 22:48):

alexcrichton closed issue #14508:

With this input:

(module
  (type $ft (func))
  (type $ct (cont $ft))
  (tag $t)
  (global $k (mut (ref null $ct)) (ref.null $ct))

  (func $body (suspend $t) (suspend $t))
  (elem declare func $body)

  (func (export "first")
    (block $h (result (ref $ct))
      (resume $ct (on $t $h) (cont.new $ct (ref.func $body)))
      (unreachable))
    (global.set $k))

  (func (export "second")
    (block $h (result (ref $ct))
      (resume $ct (on $t $h) (global.get $k))
      (unreachable))
    (global.set $k))
)
(invoke "first")
(invoke "second")

wasmtime currently panics with ASan enabled:

$ RUSTFLAGS=-Zsanitizer=address cargo +nightly run --target x86_64-unknown-linux-gnu wast ./repro.wast -W stack-switching
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running `/home/alex/code/wasmtime2/target/x86_64-unknown-linux-gnu/debug/wasmtime wast ./repro.wast -W stack-switching`

thread 'main' (712348) panicked at crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:60:14:
ASan requires the destination stack's bounds
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

thread 'main' (712348) panicked at /rustc/21b707e3f97e0b522ebd2f277a862339625ad83f/library/core/src/panicking.rs:225:5:
panic in a function that cannot unwind
stack backtrace:
   0:     0x5be5d20b2351 - std[f57a5bc8e5fe77fc]::backtrace_rs::backtrace::libunwind::trace
                               at /rustc/21b707e3f97e0b522ebd2f277a862339625ad83f/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
...

cc @dhil

If useful, an LLM report is:

<details>

ASan build: suspend to a host entry stack whose bounds were never recorded aborts

Severity: low. Only -Zsanitizer=address builds (CI "Test ASAN") with tier-3
stack switching.

Root cause

Every resume/suspend/switch in ASan builds calls
asan_start_switch_fiber(fake_stack_save, target_csi), which expects the
target's asan_stack_bottom (crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:56-62).
For the initial (host) stack, bounds are only filled by
fiber_start_complete (asan.rs:89-101) when a fresh continuation is first
entered. Each host->wasm entry gets a new VMCommonStackInformation with
asan_stack_bottom: None (stack_switching.rs:93). Resuming a continuation
started in an earlier entry and then suspending targets the new entry's
stack -> expect panics in an extern "C" fn -> abort.

Repro

repro.wast (first starts a continuation, second resumes it in a new
entry and it suspends). control.wast does both in one entry and passes.

RUSTFLAGS=-Zsanitizer=address CARGO_TARGET_DIR=target/audit-asan \
  cargo +nightly build --release --target x86_64-unknown-linux-gnu -p wasmtime-cli
target/audit-asan/x86_64-unknown-linux-gnu/release/wasmtime wast \
  -W stack-switching=y,exceptions=y,function-references=y repro.wast

Observed:

panicked at crates/wasmtime/src/runtime/vm/stack_switching/asan.rs:60:14:
ASan requires the destination stack's bounds
... panic in a function that cannot unwind
thread caused non-unwinding panic. aborting.

Non-ASan release CLI runs repro.wast fine.

Suggested fix

In finish_switch_fiber, keep the bottom_old/size_old ASan reports
(currently discarded) and store them in the parent stack info, mirroring
fiber_start_complete; or compute host stack bounds on wasm entry
(pthread_getattr_np) and set them in EntryStoreContext::enter_wasm under
cfg(asan).

</details>


Last updated: Oct 11 2026 at 02:20 UTC