servo/ports/servoshell/panic_hook.rs
Martin Robinson c9fbe018f1
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>
2024-08-06 17:43:06 +00:00

51 lines
1.6 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::io::Write;
use std::panic::PanicInfo;
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>() {
Some(s) => *s,
None => match info.payload().downcast_ref::<String>() {
Some(s) => &**s,
None => "Box<Any>",
},
};
let current_thread = thread::current();
let name = current_thread.name().unwrap_or("<unnamed>");
let stderr = std::io::stderr();
let mut stderr = stderr.lock();
if let Some(location) = info.location() {
let _ = writeln!(
&mut stderr,
"{} (thread {}, at {}:{})",
msg,
name,
location.file(),
location.line()
);
} else {
let _ = writeln!(&mut stderr, "{} (thread {})", msg, name);
}
if env::var("RUST_BACKTRACE").is_ok() {
let _ = crate::backtrace::print(&mut stderr);
}
drop(stderr);
if opts::get().hard_fail && !opts::get().multiprocess {
// 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);
}