mkaput opened issue #11957:
Wasmtime 38.0.3 produces a linker error on ARM64 macOS when building with ThinLTO enabled. The error indicates that
wasmtime_fiber_switchsymbol is undefined during linking.Undefined symbols for architecture arm64: "wasmtime_internal_fiber::stackswitch::aarch64::wasmtime_fiber_switch::hbfe01c429347756b", referenced from: wasmtime_internal_fiber::unix::Suspend::switch::h3c732376237b9f89 (.llvm.8380686341591023165) in ... wasmtime_internal_fiber::Fiber$LT$Resume$C$Yield$C$Return$GT$::resume::h3cbe31d926bc312b in ... wasmtime_internal_fiber::unix::Suspend::switch::h085493437a61cdbb in ... ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)This breaks our releases, as seen here: https://github.com/software-mansion/scarb/actions/runs/18924473454/job/54028423511.
Reverting to Wasmtime 37 workarounds this issue. The same happens when we disable LTO or use Fat LTO. This only happens with ThinLTO which is the only thing we can accept in our project due to other reasons.
Steps to Reproduce
- Architecture: ARM64 (Apple Silicon)
- OS: macOS 15.0 (Darwin 25.0.0)
- Rust: 1.90.0
- Wasmtime: 38.0.3
- Build Profile:
releasewithlto = "thin"Cargo.toml:
[package] name = "linker-repro" version = "0.1.0" edition = "2021" [dependencies] wasmtime = "38" wasmtime-wasi = "38" anyhow = "1" [profile.release] lto = "thin"src/main.rs:
use wasmtime::component::{Component, Linker}; use wasmtime::{Engine, Store}; use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView}; struct HostState { ctx: WasiCtx, table: wasmtime::component::ResourceTable, } impl WasiView for HostState { fn ctx(&mut self) -> WasiCtxView<'_> { WasiCtxView { ctx: &mut self.ctx, table: &mut self.table, } } } fn main() -> anyhow::Result<()> { let engine = Engine::default(); let mut linker = Linker::new(&engine); wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?; let component = Component::new(&engine, "(component)")?; let host_state = HostState { ctx: WasiCtx::builder().build(), table: wasmtime::component::ResourceTable::new(), }; let mut store = Store::new(&engine, host_state); let _instance = linker.instantiate(&mut store, &component)?; Ok(()) }Build command:
cargo build --releaseThis will fail with the linker error shown above.
Thoughts
- I think this regressed in 3e9eca8b23ace6b2631c557e0e84bb8371c18ed2.
- I'm not well versed in these low-level naked functions-LLVM interactions, but prompting llms guided me that there are some issues when you try to combine naked fns with LTO.
- Getting into guessing mode: could it be that ThinLTO is attempting to inline
wasmtime_fiber_switchin some places, but forgets in others?
- Is it reasonable to attach#[inline(never)]towasmtime_fiber_switch?
mkaput added the bug label to Issue #11957.
mkaput edited issue #11957:
Wasmtime 38.0.3 produces a linker error on ARM64 macOS when building with ThinLTO enabled. The error indicates that
wasmtime_fiber_switchsymbol is undefined during linking.Undefined symbols for architecture arm64: "wasmtime_internal_fiber::stackswitch::aarch64::wasmtime_fiber_switch::hbfe01c429347756b", referenced from: wasmtime_internal_fiber::unix::Suspend::switch::h3c732376237b9f89 (.llvm.8380686341591023165) in ... wasmtime_internal_fiber::Fiber$LT$Resume$C$Yield$C$Return$GT$::resume::h3cbe31d926bc312b in ... wasmtime_internal_fiber::unix::Suspend::switch::h085493437a61cdbb in ... ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)This breaks our releases, as seen here: https://github.com/software-mansion/scarb/actions/runs/18924473454/job/54028423511.
Reverting to Wasmtime 37 workarounds this issue. The same happens when we disable LTO or use Fat LTO. This only happens with ThinLTO which is the only thing we can accept in our project due to other reasons.
Steps to Reproduce
- Architecture: ARM64 (Apple Silicon)
- OS: macOS 26.0
- Rust: 1.90.0
- Wasmtime: 38.0.3
- Build Profile:
releasewithlto = "thin"Cargo.toml:
[package] name = "linker-repro" version = "0.1.0" edition = "2021" [dependencies] wasmtime = "38" wasmtime-wasi = "38" anyhow = "1" [profile.release] lto = "thin"src/main.rs:
use wasmtime::component::{Component, Linker}; use wasmtime::{Engine, Store}; use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView}; struct HostState { ctx: WasiCtx, table: wasmtime::component::ResourceTable, } impl WasiView for HostState { fn ctx(&mut self) -> WasiCtxView<'_> { WasiCtxView { ctx: &mut self.ctx, table: &mut self.table, } } } fn main() -> anyhow::Result<()> { let engine = Engine::default(); let mut linker = Linker::new(&engine); wasmtime_wasi::p2::add_to_linker_sync(&mut linker)?; let component = Component::new(&engine, "(component)")?; let host_state = HostState { ctx: WasiCtx::builder().build(), table: wasmtime::component::ResourceTable::new(), }; let mut store = Store::new(&engine, host_state); let _instance = linker.instantiate(&mut store, &component)?; Ok(()) }Build command:
cargo build --releaseThis will fail with the linker error shown above.
Thoughts
- I think this regressed in 3e9eca8b23ace6b2631c557e0e84bb8371c18ed2.
- I'm not well versed in these low-level naked functions-LLVM interactions, but prompting llms guided me that there are some issues when you try to combine naked fns with LTO.
- Getting into guessing mode: could it be that ThinLTO is attempting to inline
wasmtime_fiber_switchin some places, but forgets in others?
- Is it reasonable to attach#[inline(never)]towasmtime_fiber_switch?
bjorn3 commented on issue #11957:
wasmtime_fiber_switchwill never get inlined. Rustc implemented naked asm withglobal_asm!(). LLVM is not even aware there is a function calledwasmtime_fiber_switchduring optimizations. There is a fair chance this is a visibility bug in rustc. Can you open an issue at https://github.com/rust-lang/rust/issues/?
mkaput commented on issue #11957:
@bjorn3 makes sense, created the issue there: https://github.com/rust-lang/rust/issues/148307
I have also tried to find a more minimal reproduction, but no luck in reasonable time. Updated this issue description. Would appreciate any hints.
mkaput edited issue #11957:
Wasmtime 38.0.3 produces a linker error on ARM64 macOS when building with ThinLTO enabled. The error indicates that
wasmtime_fiber_switchsymbol is undefined during linking.error: linking with `cc` failed: exit status: 1 | = note: "cc" "<426 object files omitted>" "/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/{libwasmtime-e843f7bbc21927d3,libzstd_sys-7eabaf414ee67d02,libwasmtime_internal_jit_debug-9043bb9a4e496da8}.rlib" "<sysroot>/lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-*.rlib" "-liconv" "-lSystem" "-lc" "-lm" "-arch" "arm64" "-mmacosx-version-min=11.0.0" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-15671f59b24bbe0f/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/zstd-sys-1ea01473940232bc/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-internal-jit-debug-2aaf81cce8508d62/out" "-o" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/deps/wasmtime_only_test-69cba5150eff8962" "-Wl,-dead_strip" "-nodefaultlibs" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime-e843f7bbc21927d3.rlib[2](242b1992def1ef0b-helpers.o)) was built for newer 'macOS' version (26.0) than being linked (11.0) ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime_internal_jit_debug-9043bb9a4e496da8.rlib[2](db3b6bfb95261072-gdbjit.o)) was built for newer 'macOS' version (26.0) than being linked (11.0) Undefined symbols for architecture arm64: "wasmtime_internal_fiber::stackswitch::aarch64::wasmtime_fiber_switch::h0b241ee887e10750", referenced from: wasmtime_internal_fiber::unix::Suspend::switch::hfd4514b4efef3e13 in wasmtime_only_test-69cba5150eff8962.wasmtime-e843f7bbc21927d3.wasmtime.7e3b8021754df0c4-cgu.05.rcgu.o.rcgu.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)This breaks our releases, as seen here: https://github.com/software-mansion/scarb/actions/runs/18924473454/job/54028423511.
Reverting to Wasmtime 37 workarounds this issue. The same happens when we disable LTO or use Fat LTO. This only happens with ThinLTO which is the only thing we can accept in our project due to other reasons.
Steps to Reproduce
- Architecture: ARM64 (Apple Silicon)
- OS: macOS 26.0
- Rust: 1.90.0
- Wasmtime: 38.0.3
- Build Profile:
releasewithlto = "thin"Cargo.toml:
[package] name = "linker-repro" version = "0.1.0" edition = "2021" [dependencies] wasmtime = "38" [profile.release] lto = "thin"src/main.rs:
fn main() { let engine = wasmtime::Engine::default(); println!("Engine created: {:?}", engine); }Build command:
cargo build --releaseThis will fail with the linker error shown above.
Thoughts
- I think this regressed in 3e9eca8b23ace6b2631c557e0e84bb8371c18ed2.
- I'm not well versed in these low-level naked functions-LLVM interactions, but prompting llms guided me that there are some issues when you try to combine naked fns with LTO.
- Getting into guessing mode: could it be that ThinLTO is attempting to inline
wasmtime_fiber_switchin some places, but forgets in others?
- Is it reasonable to attach#[inline(never)]towasmtime_fiber_switch?
alexcrichton commented on issue #11957:
Thanks for the report @mkaput! Mind testing out https://github.com/bytecodealliance/wasmtime/pull/11960 and seeing if that works for you? It works for me locally but I want to double-check.
mkaput commented on issue #11957:
Yay! I can confirm #11960 works on both my reproduction and real project. Thank you
alexcrichton closed issue #11957:
Wasmtime 38.0.3 produces a linker error on ARM64 macOS when building with ThinLTO enabled. The error indicates that
wasmtime_fiber_switchsymbol is undefined during linking.error: linking with `cc` failed: exit status: 1 | = note: "cc" "<426 object files omitted>" "/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/{libwasmtime-e843f7bbc21927d3,libzstd_sys-7eabaf414ee67d02,libwasmtime_internal_jit_debug-9043bb9a4e496da8}.rlib" "<sysroot>/lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-*.rlib" "-liconv" "-lSystem" "-lc" "-lm" "-arch" "arm64" "-mmacosx-version-min=11.0.0" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-15671f59b24bbe0f/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/zstd-sys-1ea01473940232bc/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-internal-jit-debug-2aaf81cce8508d62/out" "-o" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/deps/wasmtime_only_test-69cba5150eff8962" "-Wl,-dead_strip" "-nodefaultlibs" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime-e843f7bbc21927d3.rlib[2](242b1992def1ef0b-helpers.o)) was built for newer 'macOS' version (26.0) than being linked (11.0) ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime_internal_jit_debug-9043bb9a4e496da8.rlib[2](db3b6bfb95261072-gdbjit.o)) was built for newer 'macOS' version (26.0) than being linked (11.0) Undefined symbols for architecture arm64: "wasmtime_internal_fiber::stackswitch::aarch64::wasmtime_fiber_switch::h0b241ee887e10750", referenced from: wasmtime_internal_fiber::unix::Suspend::switch::hfd4514b4efef3e13 in wasmtime_only_test-69cba5150eff8962.wasmtime-e843f7bbc21927d3.wasmtime.7e3b8021754df0c4-cgu.05.rcgu.o.rcgu.o ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)This breaks our releases, as seen here: https://github.com/software-mansion/scarb/actions/runs/18924473454/job/54028423511.
Reverting to Wasmtime 37 workarounds this issue. The same happens when we disable LTO or use Fat LTO. This only happens with ThinLTO which is the only thing we can accept in our project due to other reasons.
Steps to Reproduce
- Architecture: ARM64 (Apple Silicon)
- OS: macOS 26.0
- Rust: 1.90.0
- Wasmtime: 38.0.3
- Build Profile:
releasewithlto = "thin"Cargo.toml:
[package] name = "linker-repro" version = "0.1.0" edition = "2021" [dependencies] wasmtime = "38" [profile.release] lto = "thin"src/main.rs:
fn main() { let engine = wasmtime::Engine::default(); println!("Engine created: {:?}", engine); }Build command:
cargo build --releaseThis will fail with the linker error shown above.
Thoughts
- I think this regressed in 3e9eca8b23ace6b2631c557e0e84bb8371c18ed2.
- I'm not well versed in these low-level naked functions-LLVM interactions, but prompting llms guided me that there are some issues when you try to combine naked fns with LTO.
- Getting into guessing mode: could it be that ThinLTO is attempting to inline
wasmtime_fiber_switchin some places, but forgets in others?
- Is it reasonable to attach#[inline(never)]towasmtime_fiber_switch?
Last updated: Dec 06 2025 at 07:03 UTC