Stream: git-wasmtime

Topic: wasmtime / issue #11489 Exceptions: segmentation fault


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

vouillon opened issue #11489:

Test Case

bug.zip

Steps to Reproduce

Run the following command:

./target/debug/wasmtime  -W=all-proposals=y bug.wasm

Expected Results

It should not crash

Actual Results

I get a segfault

Versions and Environment

Wasmtime commit: 2d25f862b38abd484e5418327a9149e69d3274aa

Operating system: Linux

Architecture: x64

Extra Info

I suspect that the stack unwinder does not deal properly with tail calls.

I get the following stack trace in gdb:

#0  wasmtime::runtime::vm::ModuleRuntimeInfo::env_module (self=0x7ffeffffff68)
    at crates/wasmtime/src/runtime/vm.rs:329
#1  0x0000555557fd524f in wasmtime::runtime::vm::instance::Instance::env_module
    (self=0x7ffeffffff60) at crates/wasmtime/src/runtime/vm/instance.rs:357
#2  0x0000555557fd5fe8 in wasmtime::runtime::vm::instance::Instance::get_exported_tag (self=0x7ffeffffff60, store=..., index=...)
    at crates/wasmtime/src/runtime/vm/instance.rs:666
#3  0x0000555557fb4cad in wasmtime::runtime::vm::throw::compute_throw_action::{closure#0} (frame=0x7ffff69f48f0) at crates/wasmtime/src/runtime/vm/throw.rs:98
#4  0x0000555557f12e5e in wasmtime_internal_unwinder::throw::compute_throw_action::{closure#0}<wasmtime::runtime::vm::throw::compute_throw_action::{closure_env#0}> (frame=...) at crates/unwinder/src/throw.rs:76
#5  0x0000555558034d24 in wasmtime_internal_unwinder::stackwalk::visit_frames<wasmtime_internal_unwinder::throw::ThrowAction, wasmtime_internal_unwinder::throw::compute_throw_action::{closure_env#0}<wasmtime::runtime::vm::throw::compute_throw_action::{closure_env#0}>> (unwind=..., pc=140737353797698,
    fp=140737331026544, trampoline_fp=140737331026560, f=...)
    at crates/unwinder/src/stackwalk.rs:203
#6  0x0000555557f12c31 in wasmtime_internal_unwinder::throw::compute_throw_action<wasmtime::runtime::vm::throw::compute_throw_action::{closure_env#0}> (
    unwind=..., frame_handler=..., exit_pc=140737353797991,
    exit_trampoline_frame=140737331026368, entry_frame=140737331026560)
    at crates/unwinder/src/throw.rs:60
--Type <RET> for more, q to quit, c to continue without paging--
#7  0x0000555557da8980 in wasmtime::runtime::vm::throw::compute_throw_action (
    store=...) at crates/wasmtime/src/runtime/vm/throw.rs:120
#8  0x0000555557be3f0a in wasmtime::runtime::vm::traphandlers::call_thread_state::CallThreadState::record_unwind (self=0x7ffff69f5f30, store=..., reason=...)
    at crates/wasmtime/src/runtime/vm/traphandlers.rs:819
#9  0x0000555558088a8b in wasmtime::runtime::vm::traphandlers::catch_unwind_and_record_trap::{closure#1}<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::instance::{impl#0}::enter_host_from_wasm::{closure_env#0}<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::libcalls::raw::throw_ref::{closure_env#0}>> (info=...) at crates/wasmtime/src/runtime/vm/traphandlers.rs:136
#10 0x0000555557eff1ef in wasmtime::runtime::vm::traphandlers::tls::with<(), wasmtime::runtime::vm::traphandlers::catch_unwind_and_record_trap::{closure_env#1}<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::instance::{impl#0}::enter_host_from_wasm::{closure_env#0}<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::libcalls::raw::throw_ref::{closure_env#0}>>> (closure=...)
    at crates/wasmtime/src/runtime/vm/traphandlers.rs:1394
#11 0x0000555558084079 in wasmtime::runtime::vm::traphandlers::catch_unwind_and_record_trap<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::instance::{impl#0}::enter_host_from_wasm::{closure_env#0}<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::libcalls::raw::throw_ref::{closure_env#0}>> (
    store=..., f=...) at crates/wasmtime/src/runtime/vm/traphandlers.rs:136
#12 0x0000555557c650b2 in wasmtime::runtime::vm::instance::Instance::enter_host_from_wasm<core::result::Result<(), wasmtime::runtime::vm::traphandlers::TrapReason>, wasmtime::runtime::vm::libcalls::raw::throw_ref::{closure_env#0}> (
    vmctx=..., f=...) at crates/wasmtime/src/runtime/vm/instance.rs:265
#13 0x0000555557f6b0bb in wasmtime::runtime::vm::libcalls::raw::throw_ref (
    vmctx=..., exnref=16) at crates/wasmtime/src/runtime/vm/libcalls.rs:125

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

vouillon added the bug label to Issue #11489.

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

cfallin commented on issue #11489:

Thanks -- taking a look!

view this post on Zulip Wasmtime GitHub notifications bot (Aug 21 2025 at 17:04):

cfallin commented on issue #11489:

OK, I think the bug is that I didn't account for the tail-call arg region cleanup when computing the SP for a given frame. I had assumed that all function frames are contiguous, so FP+16 (16 coming from the unwind trait impl, but that's the value on all our 64-bit platforms) is the SP of the next higher function frame. We use that to load the dynamic context, which we use to compare dynamic tag identities of handlers. Our tail-call ABI has the callee clean up the argument region, since this is necessary to allow arbitrary-to-arbitrary-signature tail calls, and your example has a tail-call from a function of signature (func) to one of signature (func (param i32 i32 i32 i32 i32)) (which will go onto the stack on x64, because there are 6 arg regs and we use the first two for caller and callee vmctx). On x64 we use the form of the ret instruction with an SP increment for this (doesn't appear in the disassembly here, but only because $throw ends in an unconditional unreachable state because of the throw).

I believe the most robust fix for this is to reference dynamic context off of FP instead of SP -- otherwise we need metadata from functions to know their FrameLayout at runtime, which is a much bigger lift. I'll work on that.


Last updated: Dec 06 2025 at 07:03 UTC