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
Commit: 249bdf8fca (main2), audited 2026-10-02. Introduced by 11eac9de86
"[stack-switching] Interop with ASan (#14398)".Platform: Linux 7.0.0-31-generic x86_64; rustc 1.101.0-nightly (2026-09-30)
- Auditor: Claude Opus 5.5 (claude-opus-5-5); repro re-verified by coordinator
Severity: low. Only
-Zsanitizer=addressbuilds (CI "Test ASAN") with tier-3
stack switching.Root cause
Every
resume/suspend/switchin ASan builds calls
asan_start_switch_fiber(fake_stack_save, target_csi), whichexpects the
target'sasan_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 newVMCommonStackInformationwith
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 ->expectpanics in anextern "C"fn -> abort.Repro
repro.wast(firststarts a continuation,secondresumes it in a new
entry and it suspends).control.wastdoes 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.wastObserved:
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.wastfine.Suggested fix
In
finish_switch_fiber, keep thebottom_old/size_oldASan 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 inEntryStoreContext::enter_wasmunder
cfg(asan).</details>
alexcrichton added the wasm-proposal:stack-switching label to Issue #14508.
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
Commit: 249bdf8fca (main2), audited 2026-10-02. Introduced by 11eac9de86
"[stack-switching] Interop with ASan (#14398)".Platform: Linux 7.0.0-31-generic x86_64; rustc 1.101.0-nightly (2026-09-30)
- Auditor: Claude Opus 5.5 (claude-opus-5-5); repro re-verified by coordinator
Severity: low. Only
-Zsanitizer=addressbuilds (CI "Test ASAN") with tier-3
stack switching.Root cause
Every
resume/suspend/switchin ASan builds calls
asan_start_switch_fiber(fake_stack_save, target_csi), whichexpects the
target'sasan_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 newVMCommonStackInformationwith
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 ->expectpanics in anextern "C"fn -> abort.Repro
repro.wast(firststarts a continuation,secondresumes it in a new
entry and it suspends).control.wastdoes 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.wastObserved:
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.wastfine.Suggested fix
In
finish_switch_fiber, keep thebottom_old/size_oldASan 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 inEntryStoreContext::enter_wasmunder
cfg(asan).</details>
Last updated: Oct 11 2026 at 02:20 UTC