Skip to content

Commit 6f0acdc

Browse files
mrobinsonGae24
authored andcommitted
testing: Trigger a crash more reliably when panicking and hard fail is active (servo#32947)
Before when handling panics and hard-fail was activated, Servo would just exit with an error return code. This isn't interpreted as a crash by the WPT test runner. This change raises a SEGV signal instead, which means that panics should more reliably be treated as crashes. This doesn't seem to change any test results, at least any non-flaky test results. It is necessary for the test in servo#32782 to work though. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
1 parent 56cd154 commit 6f0acdc

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

ports/servoshell/crash_handler.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ pub fn install() {
1111
use std::sync::atomic;
1212
use std::thread;
1313

14-
use sig::ffi::Sig;
15-
1614
use crate::backtrace;
1715

1816
extern "C" fn handler(sig: i32) {
@@ -42,21 +40,31 @@ pub fn install() {
4240
// know to be “async-signal-safe”, which includes sigaction(), raise(),
4341
// and _exit(), but generally doesn’t include anything that allocates.
4442
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03
45-
unsafe {
46-
// Reset the signal to the default action, and reraise the signal.
47-
// Unlike libc::_exit(sig), which terminates the process normally,
48-
// this terminates abnormally just like an uncaught signal, allowing
49-
// mach (or your shell) to distinguish it from an ordinary exit, and
50-
// allows your kernel to make a core dump if configured to do so.
51-
let mut action: libc::sigaction = std::mem::zeroed();
52-
action.sa_sigaction = libc::SIG_DFL;
53-
libc::sigaction(sig, &action, std::ptr::null_mut());
54-
libc::raise(sig);
55-
}
43+
raise_signal_or_exit_with_error(sig);
5644
}
5745

58-
signal!(Sig::SEGV, handler); // handle segfaults
59-
signal!(Sig::ILL, handler); // handle stack overflow and unsupported CPUs
60-
signal!(Sig::IOT, handler); // handle double panics
61-
signal!(Sig::BUS, handler); // handle invalid memory access
46+
signal!(libc::SIGSEGV, handler); // handle segfaults
47+
signal!(libc::SIGILL, handler); // handle stack overflow and unsupported CPUs
48+
signal!(libc::SIGIOT, handler); // handle double panics
49+
signal!(libc::SIGBUS, handler); // handle invalid memory access
50+
}
51+
52+
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
53+
pub(crate) fn raise_signal_or_exit_with_error(_signal: i32) {
54+
std::process::exit(1);
55+
}
56+
57+
#[cfg(any(target_os = "macos", target_os = "linux"))]
58+
pub(crate) fn raise_signal_or_exit_with_error(signal: i32) {
59+
unsafe {
60+
// Reset the signal to the default action, and reraise the signal.
61+
// Unlike libc::_exit(sig), which terminates the process normally,
62+
// this terminates abnormally just like an uncaught signal, allowing
63+
// mach (or your shell) to distinguish it from an ordinary exit, and
64+
// allows your kernel to make a core dump if configured to do so.
65+
let mut action: libc::sigaction = std::mem::zeroed();
66+
action.sa_sigaction = libc::SIG_DFL;
67+
libc::sigaction(signal, &action, std::ptr::null_mut());
68+
libc::raise(signal);
69+
}
6270
}

ports/servoshell/panic_hook.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use std::{env, thread};
99
use log::{error, warn};
1010
use servo::config::opts;
1111

12+
use crate::crash_handler::raise_signal_or_exit_with_error;
13+
1214
pub(crate) fn panic_hook(info: &PanicInfo) {
1315
warn!("Panic hook called.");
1416
let msg = match info.payload().downcast_ref::<&'static str>() {
@@ -40,7 +42,9 @@ pub(crate) fn panic_hook(info: &PanicInfo) {
4042
drop(stderr);
4143

4244
if opts::get().hard_fail && !opts::get().multiprocess {
43-
std::process::exit(1);
45+
// When we are exiting due to a hard-failure mode, we trigger a segfault so that crash
46+
// tests detect that we crashed. If we exit normally it just looks like a non-crash exit.
47+
raise_signal_or_exit_with_error(libc::SIGSEGV);
4448
}
4549

4650
error!("{}", msg);

0 commit comments

Comments
 (0)