Add documentation about unwinding to wasm targets
This commit adds some documentation about the state of `-Cpanic=unwind` for the following wasm targets: * `wasm32-unknown-unknown` * `wasm32-wasip1` * `wasm32-wasip2` * `wasm32v1-none` Notably it's possible to use `-Cpanic=unwind` with `-Zbuild-std` and it's also mentioned that there are no concrete proposals at this time to adding a new set of targets which support unwinding. My hunch is that in a few years' time it would make sense to enable it by default on these targets (except for `wasm32v1-none`) but that's a problem for future folks to debate. For now this is an attempt to document the status quo.
This commit is contained in:
parent
f437c86ef8
commit
fd96a78092
4 changed files with 84 additions and 1 deletions
|
|
@ -157,7 +157,7 @@ $ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unkno
|
|||
```
|
||||
|
||||
Here the `mvp` "cpu" is a placeholder in LLVM for disabling all supported
|
||||
features by default. Cargo's `-Zbuild-std` feature, a Nightly Rust feature, is
|
||||
features by default. Cargo's [`-Zbuild-std`] feature, a Nightly Rust feature, is
|
||||
then used to recompile the standard library in addition to your own code. This
|
||||
will produce a binary that uses only the original WebAssembly features by
|
||||
default and no proposals since its inception.
|
||||
|
|
@ -207,3 +207,63 @@ conditionally compile code instead. This is notably different to the way native
|
|||
platforms such as x86\_64 work, and this is due to the fact that WebAssembly
|
||||
binaries must only contain code the engine understands. Native binaries work so
|
||||
long as the CPU doesn't execute unknown code dynamically at runtime.
|
||||
|
||||
## Unwinding
|
||||
|
||||
By default the `wasm32-unknown-unknown` target is compiled with `-Cpanic=abort`.
|
||||
Historically this was due to the fact that there was no way to catch panics in
|
||||
wasm, but since mid-2025 the WebAssembly [`exception-handling`
|
||||
proposal](https://github.com/WebAssembly/exception-handling) reached
|
||||
stabilization. LLVM has support for this proposal as well and when this is all
|
||||
combined together it's possible to enable `-Cpanic=unwind` on wasm targets.
|
||||
|
||||
Compiling wasm targets with `-Cpanic=unwind` is not as easy as just passing
|
||||
`-Cpanic=unwind`, however:
|
||||
|
||||
```sh
|
||||
$ rustc foo.rs -Cpanic=unwind --target wasm32-unknown-unknown
|
||||
error: the crate `panic_unwind` does not have the panic strategy `unwind`
|
||||
```
|
||||
|
||||
Notably the precompiled standard library that is shipped through Rustup is
|
||||
compiled with `-Cpanic=abort`, not `-Cpanic=unwind`. While this is the case
|
||||
you're going to be required to use Cargo's [`-Zbuild-std`] feature to build with
|
||||
unwinding support:
|
||||
|
||||
```sh
|
||||
$ RUSTFLAGS='-Cpanic=unwind' cargo +nightly build --target wasm32-unknown-unknown -Zbuild-std
|
||||
```
|
||||
|
||||
Note, however, that as of 2025-10-03 LLVM is still using the "legacy exception
|
||||
instructions" by default, not the officially standard version of the
|
||||
exception-handling proposal:
|
||||
|
||||
```sh
|
||||
$ wasm-tools validate target/wasm32-unknown-unknown/debug/foo.wasm
|
||||
error: <sysroot>/library/std/src/sys/backtrace.rs:161:5
|
||||
function `std::sys::backtrace::__rust_begin_short_backtrace` failed to validate
|
||||
|
||||
Caused by:
|
||||
0: func 2 failed to validate
|
||||
1: legacy_exceptions feature required for try instruction (at offset 0x880)
|
||||
```
|
||||
|
||||
Fixing this requires passing `-Cllvm-args=-wasm-use-legacy-eh=false` to the Rust
|
||||
compiler as well:
|
||||
|
||||
```sh
|
||||
$ RUSTFLAGS='-Cpanic=unwind -Cllvm-args=-wasm-use-legacy-eh=false' cargo +nightly build --target wasm32-unknown-unknown -Zbuild-std
|
||||
$ wasm-tools validate target/wasm32-unknown-unknown/debug/foo.wasm
|
||||
```
|
||||
|
||||
At this time there are no concrete plans for adding new targets to the Rust
|
||||
compiler which have `-Cpanic=unwind` enabled-by-default. The most likely route
|
||||
to having this enabled is that in a few years when the `exception-handling`
|
||||
target feature is enabled by default in LLVM (due to browsers/runtime support
|
||||
propagating widely enough) the targets will switch to using `-Cpanic=unwind` by
|
||||
default. This is not for certain, however, and will likely be accompanied with
|
||||
either an MCP or an RFC about changing all wasm targets in the same manner. In
|
||||
the meantime using `-Cpanic=unwind` will require using [`-Zbuild-std`] and
|
||||
passing the appropriate flags to rustc.
|
||||
|
||||
[`-Zbuild-std`]: ../../cargo/reference/unstable.html#build-std
|
||||
|
|
|
|||
|
|
@ -133,3 +133,9 @@ to Rust 1.80 the `target_env` condition was not set.
|
|||
The default set of WebAssembly features enabled for compilation is currently the
|
||||
same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the
|
||||
documentation there for more information.
|
||||
|
||||
## Unwinding
|
||||
|
||||
This target is compiled with `-Cpanic=abort` by default. For information on
|
||||
using `-Cpanic=unwind` see the [documentation about unwinding for
|
||||
`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md#unwinding).
|
||||
|
|
|
|||
|
|
@ -67,3 +67,9 @@ It's recommended to conditionally compile code for this target with:
|
|||
The default set of WebAssembly features enabled for compilation is currently the
|
||||
same as [`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md). See the
|
||||
documentation there for more information.
|
||||
|
||||
## Unwinding
|
||||
|
||||
This target is compiled with `-Cpanic=abort` by default. For information on
|
||||
using `-Cpanic=unwind` see the [documentation about unwinding for
|
||||
`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md#unwinding).
|
||||
|
|
|
|||
|
|
@ -107,3 +107,14 @@ $ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unkno
|
|||
Which not only rebuilds `std`, `core` and `alloc` (which is somewhat costly and annoying) but more importantly requires the use of nightly Rust toolchains (for the `-Zbuild-std` flag). This is very undesirable for the target audience, which consists of people targeting WebAssembly implementations that prioritize stability, simplicity and/or security over feature support.
|
||||
|
||||
This `wasm32v1-none` target exists as an alternative option that works on stable Rust toolchains, without rebuilding the stdlib.
|
||||
|
||||
## Unwinding
|
||||
|
||||
This target is compiled with `-Cpanic=abort` by default. Using `-Cpanic=unwind`
|
||||
would require using the WebAssembly exception-handling proposal stabilized
|
||||
mid-2025, and if that's desired then you most likely don't want to use this
|
||||
target and instead want to use `wasm32-unknown-unknown` instead. It's unlikely
|
||||
that this target will ever support unwinding with the precompiled artifacts
|
||||
shipped through rustup. For documentation about using `-Zbuild-std` to enable
|
||||
using `-Cpanic=unwind` see the [documentation of
|
||||
`wasm32-unknown-unknown`](./wasm32-unknown-unknown.md#unwinding).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue