mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +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::sync::atomic;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use sig::ffi::Sig;
|
|
||||||
|
|
||||||
use crate::backtrace;
|
use crate::backtrace;
|
||||||
|
|
||||||
extern "C" fn handler(sig: i32) {
|
extern "C" fn handler(sig: i32) {
|
||||||
|
@ -42,6 +40,22 @@ pub fn install() {
|
||||||
// know to be “async-signal-safe”, which includes sigaction(), raise(),
|
// know to be “async-signal-safe”, which includes sigaction(), raise(),
|
||||||
// and _exit(), but generally doesn’t include anything that allocates.
|
// 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
|
// 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 {
|
unsafe {
|
||||||
// Reset the signal to the default action, and reraise the signal.
|
// Reset the signal to the default action, and reraise the signal.
|
||||||
// Unlike libc::_exit(sig), which terminates the process normally,
|
// 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.
|
// allows your kernel to make a core dump if configured to do so.
|
||||||
let mut action: libc::sigaction = std::mem::zeroed();
|
let mut action: libc::sigaction = std::mem::zeroed();
|
||||||
action.sa_sigaction = libc::SIG_DFL;
|
action.sa_sigaction = libc::SIG_DFL;
|
||||||
libc::sigaction(sig, &action, std::ptr::null_mut());
|
libc::sigaction(signal, &action, std::ptr::null_mut());
|
||||||
libc::raise(sig);
|
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 log::{error, warn};
|
||||||
use servo::config::opts;
|
use servo::config::opts;
|
||||||
|
|
||||||
|
use crate::crash_handler::raise_signal_or_exit_with_error;
|
||||||
|
|
||||||
pub(crate) fn panic_hook(info: &PanicInfo) {
|
pub(crate) fn panic_hook(info: &PanicInfo) {
|
||||||
warn!("Panic hook called.");
|
warn!("Panic hook called.");
|
||||||
let msg = match info.payload().downcast_ref::<&'static str>() {
|
let msg = match info.payload().downcast_ref::<&'static str>() {
|
||||||
|
@ -40,7 +42,9 @@ pub(crate) fn panic_hook(info: &PanicInfo) {
|
||||||
drop(stderr);
|
drop(stderr);
|
||||||
|
|
||||||
if opts::get().hard_fail && !opts::get().multiprocess {
|
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);
|
error!("{}", msg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue