Skip to content

Exception handling instructions emitted on wasm even when exception-handling feature is disabled #140293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bjorn3 opened this issue Apr 25, 2025 · 2 comments
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. F-c_unwind `#![feature(c_unwind)]` O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@bjorn3
Copy link
Member

bjorn3 commented Apr 25, 2025

I tried this code:

pub extern "C-unwind" fn gzgetc() -> i32 {
    42
}

pub extern "C-unwind" fn gzgetc_() -> i32 {
    gzgetc()
}

fn main() {
    for gzgetc_fn in [gzgetc, gzgetc_] {
        // gzgetc on a null file handle should return -1.
        assert_eq!(gzgetc_fn(), -1);
    }
}

compiled for wasm32-wasip1 or wasm32-unknown-unknown without -Ctarget-feature=exception-handling.

I expected to see this happen: No exception handling instructions emitted

Instead, this happened: catch_call is emitted for gzgetc_fn() when opt-level < 2.

Meta

rustc --version --verbose: Both 1.86 and nightly

This is causing failure to run on Wasmtime in some cases: trifectatechfoundation/zlib-rs#352 (comment)

@bjorn3 bjorn3 added C-bug Category: This is a bug. F-c_unwind `#![feature(c_unwind)]` O-wasm Target: WASM (WebAssembly), http://webassembly.org/ labels Apr 25, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 25, 2025
@alexcrichton
Copy link
Member

reduced slightly it looks like this generates exception-handling instructions too:

#[unsafe(no_mangle)]
pub extern "C-unwind" fn foo(x: extern "C-unwind" fn()) {
   x()
}

@alexcrichton
Copy link
Member

Digging in a bit more:

I think what's happening here is that the AbortUnwindingCalls pass is running and in -Cpanic=abort mode it's inserting a panicking shim around the invocation of this function pointer as, on native at least, the origin of the pointer could be an FFI definition which does actually unwind which would not be sound in Rust. I believe this is also why function pointers are required because calling a defined function in Rust has a special case of "we know that can't unwind" so the cleanuppad is skipped.

Two solutions I can think of are:

  • Check for -Ctarget-feature=+exception-handling in AbortUnwindingCalls -- on one hand I think the fix for this is to add logic along the lines of "can this target ever possibly unwind?" and if the answer is "no" then the AbortUnwindingCalls pass is skipped. Sort of at least, passing -Z mir-enable-passes=-AbortUnwindingCalls results in an ICE so AbortUnwindingCalls needs to run to some degree. This then raises some uncomfortable ABI questions. For example it means you shouldn't be able to invoke -Ctarget-feature=+exception-handling for just one crate, it has to be true for an entire compilation. This means that when using precompiled standard libraries it should not be possible to turn on the +exception-handling feature, but using that would require -Zbuild-std in one form or another.
  • Punt this to LLVM - another possible solution would be to file an issue with LLVM and request that these instructions turn into noops when the exception-handling target feature is disabled. I'm not sure how amenable LLVM would be to this though.

IIRC I remember seeing messages awhile back about "global" target features which is sort of what we'd want here I think, but I'm not sure if that implementation/idea materialized

@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-target-feature Area: Enabling/disabling target features like AVX, Neon, etc. C-bug Category: This is a bug. F-c_unwind `#![feature(c_unwind)]` O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants