Skip to content

Commit 83a4c4a

Browse files
authored
Disable signals-based-traps in s390x in CI (#13537)
* Disable signals-based-traps in s390x in CI The many-failures-per-week is becoming quite onerous. I'm getting more desperate to try anything to at least work around this issue. This is an attempt based on LLM-analysis saying that the signal handler has funny things going on. No idea if this will fix anything, and we'll have to monitor this over time. Otherwise this is intended to be as lightweight and unobtrusive as possible to make it easy to excise if needed. * Try to fix warnings * Try another cfg combo prtest:full * Adjust some tests * Adjust attributes * Adjust test
1 parent 2681cc8 commit 83a4c4a

6 files changed

Lines changed: 47 additions & 17 deletions

File tree

crates/wasmtime/build.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ fn main() {
2424

2525
let has_native_signals = !miri
2626
&& (supported_os || cfg!(feature = "custom-native-signals"))
27-
&& has_host_compiler_backend;
27+
&& has_host_compiler_backend
28+
&& !is_buggy_s390x_qemu_emulation();
2829
let has_virtual_memory = supported_os || cfg!(feature = "custom-virtual-memory");
2930
let has_custom_sync = !cfg!(feature = "std")
3031
&& cfg!(feature = "custom-sync-primitives")
@@ -59,6 +60,21 @@ fn main() {
5960
}
6061
}
6162

63+
// Attempts to detect if we're running in Wasmtime's CI, testing s390x, and
64+
// testing s390x under QEMU. In this situation we're experiencing flaky
65+
// failures, more info in #10000, and current LLM-based analysis seems to point
66+
// to the signal handler state being corrupted in emulation. We're seeing
67+
// many spurious failures per week so this is a bit of a last-ditch attempt to
68+
// work around the issue. In this situation we pretend that native signals are
69+
// not available for s390x which forces disabling signals-based-traps which in
70+
// theory means we don't rely on signal handlers...
71+
fn is_buggy_s390x_qemu_emulation() -> bool {
72+
std::env::var("CI").is_ok()
73+
&& std::env::var("WASMTIME_TEST_NO_HOG_MEMORY").is_ok()
74+
&& std::env::var("QEMU_BUILD_VERSION").is_ok()
75+
&& std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "s390x"
76+
}
77+
6278
fn cfg(key: &str) -> bool {
6379
std::env::var(&format!("CARGO_CFG_{}", key.to_uppercase())).is_ok()
6480
}

crates/wasmtime/src/engine/serialization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ mod test {
610610
}
611611

612612
#[test]
613-
#[cfg_attr(miri, ignore)]
613+
#[cfg_attr(any(miri, not(has_native_signals)), ignore)]
614614
#[cfg(target_pointer_width = "64")] // different defaults on 32-bit platforms
615615
fn test_tunables_int_mismatch() -> Result<()> {
616616
let engine = Engine::default();

crates/wasmtime/src/runtime/vm/interpreter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ impl InterpreterRef<'_> {
483483
}
484484

485485
// Not possible with our closure above returning `false`.
486-
#[cfg(has_host_compiler_backend)]
486+
#[cfg(has_native_signals)]
487487
TrapTest::HandledByEmbedder => unreachable!(),
488488

489489
// Trap was handled, yay! Configure interpreter state

crates/wasmtime/src/runtime/vm/traphandlers.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! WebAssembly trap handling, which is built on top of the lower-level
22
//! signalhandling mechanisms.
33
4+
#![cfg_attr(
5+
all(not(has_native_signals), not(feature = "pulley")),
6+
expect(unused, reason = "easier to not #[cfg] methods and all related types")
7+
)]
8+
49
mod backtrace;
510

611
#[cfg(feature = "coredump")]
@@ -51,8 +56,7 @@ pub(crate) enum TrapTest {
5156
/// Not a wasm trap, need to delegate to whatever process handler is next.
5257
NotWasm,
5358
/// This trap was handled by the embedder via custom embedding APIs.
54-
#[cfg(has_host_compiler_backend)]
55-
#[cfg_attr(miri, expect(dead_code, reason = "using #[cfg] too unergonomic"))]
59+
#[cfg(all(has_native_signals, not(miri)))]
5660
HandledByEmbedder,
5761
/// This is a wasm trap, it needs to be handled.
5862
Trap(Handler),

tests/all/pooling_allocator.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,13 @@ fn dynamic_memory_pooling_allocator() -> Result<()> {
713713
) else {
714714
// Ignore invalid configurations on 32-bit which can't run with
715715
// signals-based-traps.
716-
assert!(cfg!(target_pointer_width = "32") && signals_based_traps);
716+
//
717+
// Note that s390x in CI also skip this because it's not using
718+
// signals-based-traps.
719+
assert!(
720+
cfg!(target_arch = "s390x")
721+
|| (cfg!(target_pointer_width = "32") && signals_based_traps)
722+
);
717723
continue;
718724
};
719725

tests/all/traps.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,9 +1303,11 @@ fn div_plus_load_reported_right() -> Result<()> {
13031303

13041304
#[test]
13051305
fn wasm_fault_address_reported_by_default() -> Result<()> {
1306-
let engine = Engine::default();
1306+
let mut config = Config::new();
1307+
config.signals_based_traps(true);
1308+
let engine = Engine::new(&config)?;
13071309
let mut store = Store::new(&engine, ());
1308-
let module = Module::new(
1310+
let Ok(module) = Module::new(
13091311
&engine,
13101312
r#"
13111313
(module
@@ -1317,7 +1319,12 @@ fn wasm_fault_address_reported_by_default() -> Result<()> {
13171319
(start $start)
13181320
)
13191321
"#,
1320-
)?;
1322+
) else {
1323+
// This test requires a host that supports signals-based-traps to report
1324+
// the faulting address. If that configuration isn't supported by this
1325+
// host then skip the test.
1326+
return Ok(());
1327+
};
13211328
let err = Instance::new(&mut store, &module, &[]).unwrap_err();
13221329

13231330
// NB: at this time there's no programmatic access to the fault address
@@ -1329,15 +1336,12 @@ fn wasm_fault_address_reported_by_default() -> Result<()> {
13291336
// It looks like the exact reported fault address may not be deterministic,
13301337
// so assert that we have the right error message, but not the exact
13311338
// address.
1332-
//
1333-
// Skip 32-bit platforms here which currently all use Pulley and don't use
1334-
// virtual memory for catching traps. This means that the trap error isn't
1335-
// available.
13361339
let err = format!("{err:?}");
1337-
let contains_address = err.contains("memory fault at wasm address ")
1338-
&& err.contains(" in linear memory of size 0x10000");
1339-
let address_expected = cfg!(target_pointer_width = "64");
1340-
assert_eq!(contains_address, address_expected, "bad error: {err}");
1340+
assert!(
1341+
err.contains("memory fault at wasm address ")
1342+
&& err.contains(" in linear memory of size 0x10000"),
1343+
"bad error: {err}"
1344+
);
13411345
Ok(())
13421346
}
13431347

0 commit comments

Comments
 (0)