Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit 7f8370a

Browse files
authored
Fix ASAN in combination with throw intrinsic (#10974)
* Fix ASAN in combination with throw intrinsic Prior to this commit locally I would see a nondeterministic crash when executing: RUSTFLAGS=-Zsanitizer=address \ cargo +nightly run --release test filetests The crash has a scary-looking internal assertion within the ASAN runtime itself and local debugging seems to show that threads are required to reproduce this and it's nondeterministic. I don't know why CI is currently passing on all PRs when this is failing so frequently for myself locally. In any case it seems like there's a magical ASAN intrinsic to call before `noreturn` things which I think is intended for thread-stopping events which isn't a great fit for exceptions here but it seems to resolve the crash. Basically I have no idea why things crash locally, what this new function does, nor why it fixes things. I am but a slave to the CI gods in an attempt to make it so our CI is more reliable. * Fix compile warning
1 parent f4a9644 commit 7f8370a

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

crates/unwinder/build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn main() {
2+
// NB: duplicating a workaround in the wasmtime-fiber build script.
3+
custom_cfg("asan", cfg_is("sanitize", "address"));
4+
}
5+
6+
fn cfg_is(key: &str, val: &str) -> bool {
7+
std::env::var(&format!("CARGO_CFG_{}", key.to_uppercase()))
8+
.ok()
9+
.as_deref()
10+
== Some(val)
11+
}
12+
13+
fn custom_cfg(key: &str, enabled: bool) {
14+
println!("cargo:rustc-check-cfg=cfg({key})");
15+
if enabled {
16+
println!("cargo:rustc-cfg={key}");
17+
}
18+
}

crates/unwinder/src/arch/mod.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,37 @@ cfg_if::cfg_if! {
6161
/// - The Rust frames between the unwind destination and this
6262
/// frame to be unwind-safe: that is, they cannot have `Drop`
6363
/// handlers for which safety requires that they run.
64-
pub use imp::resume_to_exception_handler;
64+
pub unsafe fn resume_to_exception_handler(
65+
pc: usize,
66+
sp: usize,
67+
fp: usize,
68+
payload1: usize,
69+
payload2: usize,
70+
) -> ! {
71+
// Without this ASAN seems to nondeterministically trigger an
72+
// internal assertion when running tests with threads. Not entirely
73+
// clear what's going on here but it seems related to the fact that
74+
// there's Rust code on the stack which is never cleaned up due to
75+
// the jump out of `imp::resume_to_exception_handler`.
76+
//
77+
// This function is documented as something that should be called to
78+
// clean up the entire thread's shadow memory and stack which isn't
79+
// exactly what we want but this at least seems to resolve ASAN
80+
// issues for now. Probably a heavy hammer but better than false
81+
// positives I suppose...
82+
#[cfg(asan)]
83+
{
84+
unsafe extern "C" {
85+
fn __asan_handle_no_return();
86+
}
87+
unsafe {
88+
__asan_handle_no_return();
89+
}
90+
}
91+
unsafe {
92+
imp::resume_to_exception_handler(pc, sp, fp, payload1, payload2)
93+
}
94+
}
6595

6696
/// Get the return address in the function at the next-older
6797
/// frame from the given FP.

0 commit comments

Comments
 (0)