1use std::io::Write;
6use std::panic::PanicHookInfo;
7use std::{env, thread};
8
9use log::{error, warn};
10use servo::config::opts;
11
12use crate::crash_handler::raise_signal_or_exit_with_error;
13
14pub(crate) fn panic_hook(info: &PanicHookInfo) {
15 warn!("Panic hook called.");
16 let msg = match info.payload().downcast_ref::<&'static str>() {
17 Some(s) => *s,
18 None => match info.payload().downcast_ref::<String>() {
19 Some(s) => &**s,
20 None => "Box<Any>",
21 },
22 };
23 let current_thread = thread::current();
24 let name = current_thread.name().unwrap_or("<unnamed>");
25 let stderr = std::io::stderr();
26 let mut stderr = stderr.lock();
27 if let Some(location) = info.location() {
28 let _ = writeln!(
29 &mut stderr,
30 "{} (thread {}, at {}:{})",
31 msg,
32 name,
33 location.file(),
34 location.line()
35 );
36 } else {
37 let _ = writeln!(&mut stderr, "{} (thread {})", msg, name);
38 }
39 if env::var("RUST_BACKTRACE").is_ok() {
40 let _ = crate::backtrace::print(&mut stderr);
41 }
42 drop(stderr);
43
44 if opts::get().hard_fail && !opts::get().multiprocess {
47 raise_signal_or_exit_with_error(libc::SIGSEGV);
50 }
51
52 error!("{}", msg);
53}