For panic=unwind on Wasm targets, define __cpp_exception tag#1077
For panic=unwind on Wasm targets, define __cpp_exception tag#1077hoodmane wants to merge 1 commit intorust-lang:mainfrom
Conversation
| // | ||
| // Emscripten provides this tag in its runtime libraries, so we don't need to | ||
| // define it for Emscripten targets. Including this in Emscripten would break | ||
| // the wasm-cpp-exception-tag test. |
There was a problem hiding this comment.
For wasi should this be provided by wasi-libc in case C++ code is used?
There was a problem hiding this comment.
I am not sure what is happening with wasi cc @alexcrichton . But I'm happy to guard this to also be skipped on wasi if we think that's the right choice. I think the only case where there could be problems is with dynamic linking.
There was a problem hiding this comment.
I'd agree with bjorn3 that this shouldn't be defined here, but in general with dynamic linking I don't think this should be defined in compiler-builtins either because that would mean that there'd be an exception-type-per-shared-object which I don't think is what's desired.
Is this just for Emscripten targets? If so, shouldn't Emscripten be the one providing this definition? If this isn't for Emscripten, is it for wasm32-unknown-unknown? If so where does Rust end up needing __cpp_exception from?
There was a problem hiding this comment.
It is for wasm32-unknown-unknown. I have a cfg on this code that excludes Emscripten because Emscripten is already handling it. Rust uses cpp_exception for panics and catch_unwind. It is emitted by llvm, and by default it will import it from env.__cpp_exception unless you define the symbol explicitly. wasm-bindgen is currently using walrus to transform the generated module and convert the __cpp_exception import into a tag definition:
https://github.com/wasm-bindgen/wasm-bindgen/pull/4938/changes#diff-8d702d8da596b2105e4e94a3855489a49792843bd621954a3feacf845b6d42afR375-R389
There was a problem hiding this comment.
Specifically, panic uses the wasm_throw llvm intrinsic and catch_unwind uses the wasm_catch llvm intrinsic. Both of these intrinsics generate a reference to this symbol:
wasm_throw definition
wasm_catch definition
__cpp_exception symbol generated here
There was a problem hiding this comment.
Makes sense, thanks for the info. In that situation though this definition I think might be best to reside in the unwind crate in the standard library? There's no need to have it compiler-builtins specifically and unwinding is the true source of the symbol as well?
Additionally I think it would be good to restrict it to target_os="unknown" to only affect wasm32-unknown-unknown. The responsibility for defining this symbol on other toolchains lies elsewhere (e.g. with Emscripten or WASI targets). External toolchains will have more knowledge of what to do in the face of shared libraries, for example.
|
If this just needs to be a completely empty function body, could this just be: intrinsics! {
#[unsafe(naked)]
pub fn __cpp_exception -> usize {
core::arch::naked_asm!("");
}
}
Also if you rebase, CI should be working again. |
Since llvm/llvm-project 159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind. See also rust-lang/rust 152241 which includes a test for this change.
4ed4fcf to
ff572dd
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
It shouldn't be making a function at all. It is defining a wasm-eh exception tag. For reference here is the corresponding code in compiler-builtins: I think the weak linkage works out alright -- for instance it worked when I removed the |
|
I don't think the symbol is weak as-is, did it complain if linker errors are enabled? Adding the following gets what I think we want and I think should address the dylib concern: ".weak __cpp_exception",
".hidden __cpp_exception",Though I'm curious why LLVM doesn't do this. |
|
For dylibs specifically my concern is that compiler-rt is the wrong place for this symbol. Compiler-builtins is linked to all crates and is intended to be linked statically, but this symbol needs to be defined precisely once amongst a set of dynamic libraries to have exceptions work correctly (e.g. otherwise you couldn't throw in one dylib and catch in another). Solving that would require |
|
@tgross35 that makes sense to me I can add those. Though as you say, llvm doesn't set that stuff. @sbc100 can you explain what's going on? Particularly regarding the previous two comments on symbol visibility and dynamic linking. I see in Emscripten that libcxxabi always includes |
|
Ideally LLVM would allow us to define our own rust exception tag that we could define in eg libcore. This would also avoid the need for the exception canary on wasm (we did still need it on native though). |
In emscripten we only link libcxxabi into the main program and never into shared libraries so there should always only be one definition of these things. (We also only link compiler-rt into the main program BTW). If you want to add |
Rustc does link compiler-builtins into every dylib however and uses hidden visibility for all symbols in it. |
|
I see, in that case maybe compiler-builtins is not the right place for this symbol after all, since it is required to have just once definition across the whole program. Maybe it should live in Alternatively it could be defined weakly so that just one definition will be chosen by the dyanmic linker. |
|
Or is |
|
Probably not |
|
Personally, yeah, my read on this is that this would be well-suited for When in I do agree with @bjorn3, however, where it would be best for Rust to be able to define its own tag type. That way we wouldn't have to worry about any of this and |
|
@alexcrichton do you mean that panics shouldn't be C++ exceptions anymore? Or would this only apply to the |
|
I've updated rust-lang/rust#152241 based on the feedback here. Thanks everyone! |
|
I'd ideally like that for Rust panics on all WebAssembly targets that a Rust-specific |
…ption, r=alexcrichton For panic=unwind on Wasm targets, define __cpp_exception tag Since llvm/llvm-project#159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind. Same changes applied to compiler-builtins: rust-lang/compiler-builtins#1077 See wasm-bindgen/wasm-bindgen#4938 for a downstream workaround. cc @sbc100
Rollup merge of #152241 - hoodmane:wasm-unwind-link-cpp-exception, r=alexcrichton For panic=unwind on Wasm targets, define __cpp_exception tag Since llvm/llvm-project#159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind. Same changes applied to compiler-builtins: rust-lang/compiler-builtins#1077 See wasm-bindgen/wasm-bindgen#4938 for a downstream workaround. cc @sbc100
…alexcrichton For panic=unwind on Wasm targets, define __cpp_exception tag Since llvm/llvm-project#159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind. Same changes applied to compiler-builtins: rust-lang/compiler-builtins#1077 See wasm-bindgen/wasm-bindgen#4938 for a downstream workaround. cc @sbc100
…alexcrichton For panic=unwind on Wasm targets, define __cpp_exception tag Since llvm/llvm-project#159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind. Same changes applied to compiler-builtins: rust-lang/compiler-builtins#1077 See wasm-bindgen/wasm-bindgen#4938 for a downstream workaround. cc @sbc100
Since llvm/llvm-project#159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind.
See also rust-lang/rust#152241 which includes a test for this change.