use std::io::Write;
use std::panic::PanicHookInfo;
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: &PanicHookInfo) {
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 {
raise_signal_or_exit_with_error(libc::SIGSEGV);
}
error!("{}", msg);
}