/* 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::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::() { Some(s) => &**s, None => "Box", }, }; let current_thread = thread::current(); let name = current_thread.name().unwrap_or(""); 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); // TODO: This shouldn't be using internal Servo options here. Perhaps this functionality should // move into libservo itself. 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); }