Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion library/panic_unwind/src/gcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
unsafe {
let exception = ptr as *mut uw::_Unwind_Exception;
if (*exception).exception_class != RUST_EXCEPTION_CLASS {
uw::_Unwind_DeleteException(exception);
if let Some(exception_cleanup) = (*exception).exception_cleanup {
exception_cleanup(uw::_URC_FOREIGN_EXCEPTION_CAUGHT, exception);
}
Comment on lines -89 to +91

@alexcrichton alexcrichton Jul 29, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the breadth of libunwind implementations, how confident are you that all implementations basically look like this? I'd expect some libunwind somewhere to do something weird for example which means that this might be a regression.

View changes since the review

super::__rust_foreign_exception();
}

Expand Down
15 changes: 9 additions & 6 deletions library/unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ cfg_select! {
target_env = "msvc" => {
// Windows MSVC no extra unwinder support needed
}
target_family = "wasm" => {
mod types;
mod wasm;
pub use wasm::*;
}
any(
target_os = "l4re",
target_os = "none",
Expand All @@ -32,18 +37,12 @@ cfg_select! {
target_os = "psp",
target_os = "solid_asp3",
all(target_vendor = "fortanix", target_env = "sgx"),
all(target_os = "wasi", panic = "unwind"),

@alexcrichton alexcrichton Jul 29, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I feel it'll work best to "pretend like you're native" on WASI as opposed to having wasm-specific code here. You've already got concerns about possible future LLVM changes/evolutions, for example, and presumably libunwind would be kept in sync which means Rust wouldn't have to explicitly keep in sync.

Have you tested this on WASI targets to see if it works? I remember dealing with __cpp_exception is finnicky and difficult to precisely align.

View changes since the review

@bjorn3 bjorn3 Jul 29, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WASI is already not native in that we don't have a personality function on wasm and consequently all functions that the personality function would normally need to call are entirely missing on wasm.

You've already got concerns about possible future LLVM changes/evolutions, for example, and presumably libunwind would be kept in sync which means Rust wouldn't have to explicitly keep in sync.

We already would need to adapt to LLVM changes on wasm32-unknown-unknown. This PR merely makes that code used on all wasm targets.

Have you tested this on WASI targets to see if it works?

Not yet.

I remember dealing with __cpp_exception is finnicky and difficult to precisely align.

It should still be using __cpp_exception from libunwind.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend testing this change. "Should work" I have found often means "there's some subtle reason that this doesn't actually work", especially when it comes to things like this.

For WASI libunwind is already linked, so I think it's best to use it directly instead of going behind it to throw an exception.

target_os = "xous",
) => {
mod libunwind;
pub use libunwind::*;
mod types;
}
target_family = "wasm" => {
mod types;
mod wasm;
pub use wasm::*;
}
_ => {
// no unwinder on the system!
// - os=none ("bare metal" targets)
Expand Down Expand Up @@ -215,6 +214,10 @@ cfg_select! {
#[link(name = "gcc_s")]
unsafe extern "C" {}

#[cfg(all(target_os = "wasi", panic = "unwind"))]
#[link(name = "unwind")]
unsafe extern "C" {}

#[cfg(all(target_os = "windows", target_env = "gnu", target_abi = "llvm"))]
#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))]
#[link(name = "unwind", cfg(not(target_feature = "crt-static")))]
Expand Down
8 changes: 0 additions & 8 deletions library/unwind/src/libunwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,10 @@ pub enum _Unwind_Context {}
all(feature = "llvm-libunwind", any(target_os = "fuchsia", target_os = "linux")),
link(name = "unwind", kind = "static", modifiers = "-bundle")
)]
// Explicitly link the `unwind` library on WASI targets.
//
// This is provided in the self-contained sysroot for WASI targets by default.
// Note that Rust defaults to `-Cpanic=abort` on WASI targets meaning that this
// doesn't end up getting used by default, but this does mean that with
// `-Zbuild-std` this'll automatically link it in.
#[cfg_attr(target_os = "wasi", link(name = "unwind"))]
unsafe extern "C-unwind" {
pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
}
unsafe extern "C" {
pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
pub fn _Unwind_GetTextRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
Expand Down
1 change: 0 additions & 1 deletion library/unwind/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub const unwinder_private_data_size: usize = cfg_select! {
target_arch = "s390x" => 2,
any(target_arch = "sparc", target_arch = "sparc64") => 2,
any(target_arch = "riscv64", target_arch = "riscv32") => 2,
all(target_family = "wasm", target_os = "emscripten") => 20,
target_family = "wasm" => 2,
target_arch = "hexagon" => 5,
any(target_arch = "loongarch32", target_arch = "loongarch64") => 2,
Expand Down
6 changes: 0 additions & 6 deletions library/unwind/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ core::arch::global_asm!(

pub use crate::types::*;

pub unsafe fn _Unwind_DeleteException(exception: *mut _Unwind_Exception) {
if let Some(exception_cleanup) = unsafe { (*exception).exception_cleanup } {
exception_cleanup(_URC_FOREIGN_EXCEPTION_CAUGHT, exception);
}
}

pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
// This implementation is only used for `wasm*-unknown-unknown` targets. Such targets are not
// guaranteed to support exceptions, and they default to `-C panic=abort`. Because an unknown
Expand Down
Loading