| /* 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::<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); |
| |
| // 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); |
| } |