mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
testing: Trigger a crash more reliably when panicking and hard fail is active (#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 #32782 to work though. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
89d20fc401
commit
c9fbe018f1
2 changed files with 30 additions and 18 deletions
|
@ -11,8 +11,6 @@ pub fn install() {
|
|||
use std::sync::atomic;
|
||||
use std::thread;
|
||||
|
||||
use sig::ffi::Sig;
|
||||
|
||||
use crate::backtrace;
|
||||
|
||||
extern "C" fn handler(sig: i32) {
|
||||
|
@ -42,6 +40,22 @@ pub fn install() {
|
|||
// know to be “async-signal-safe”, which includes sigaction(), raise(),
|
||||
// and _exit(), but generally doesn’t include anything that allocates.
|
||||
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03_03
|
||||
raise_signal_or_exit_with_error(sig);
|
||||
}
|
||||
|
||||
signal!(libc::SIGSEGV, handler); // handle segfaults
|
||||
signal!(libc::SIGILL, handler); // handle stack overflow and unsupported CPUs
|
||||
signal!(libc::SIGIOT, handler); // handle double panics
|
||||
signal!(libc::SIGBUS, handler); // handle invalid memory access
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||
pub(crate) fn raise_signal_or_exit_with_error(_signal: i32) {
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
pub(crate) fn raise_signal_or_exit_with_error(signal: i32) {
|
||||
unsafe {
|
||||
// Reset the signal to the default action, and reraise the signal.
|
||||
// Unlike libc::_exit(sig), which terminates the process normally,
|
||||
|
@ -50,13 +64,7 @@ pub fn install() {
|
|||
// allows your kernel to make a core dump if configured to do so.
|
||||
let mut action: libc::sigaction = std::mem::zeroed();
|
||||
action.sa_sigaction = libc::SIG_DFL;
|
||||
libc::sigaction(sig, &action, std::ptr::null_mut());
|
||||
libc::raise(sig);
|
||||
libc::sigaction(signal, &action, std::ptr::null_mut());
|
||||
libc::raise(signal);
|
||||
}
|
||||
}
|
||||
|
||||
signal!(Sig::SEGV, handler); // handle segfaults
|
||||
signal!(Sig::ILL, handler); // handle stack overflow and unsupported CPUs
|
||||
signal!(Sig::IOT, handler); // handle double panics
|
||||
signal!(Sig::BUS, handler); // handle invalid memory access
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ use std::{env, thread};
|
|||
use log::{error, warn};
|
||||
use servo::config::opts;
|
||||
|
||||
use crate::crash_handler::raise_signal_or_exit_with_error;
|
||||
|
||||
pub(crate) fn panic_hook(info: &PanicInfo) {
|
||||
warn!("Panic hook called.");
|
||||
let msg = match info.payload().downcast_ref::<&'static str>() {
|
||||
|
@ -40,7 +42,9 @@ pub(crate) fn panic_hook(info: &PanicInfo) {
|
|||
drop(stderr);
|
||||
|
||||
if opts::get().hard_fail && !opts::get().multiprocess {
|
||||
std::process::exit(1);
|
||||
// When we are exiting due to a hard-failure mode, we trigger a segfault so that crash
|
||||
// tests detect that we crashed. If we exit normally it just looks like a non-crash exit.
|
||||
raise_signal_or_exit_with_error(libc::SIGSEGV);
|
||||
}
|
||||
|
||||
error!("{}", msg);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue