pub fn register_trap_handlers() {
#[cfg(unix)]
register_unix_handlers();
#[cfg(windows)]
register_windows_handlers();
}
#[cfg(unix)]
fn register_unix_handlers() {
unsafe {
libc::signal(
libc::SIGSEGV,
backtrace_handler as *const () as libc::sighandler_t,
);
libc::signal(
libc::SIGILL,
backtrace_handler as *const () as libc::sighandler_t,
);
libc::signal(
libc::SIGBUS,
backtrace_handler as *const () as libc::sighandler_t,
);
}
}
#[cfg(windows)]
fn register_windows_handlers() {
unsafe {
libc::signal(
libc::SIGSEGV,
backtrace_handler as *const () as libc::sighandler_t,
);
libc::signal(
libc::SIGILL,
backtrace_handler as *const () as libc::sighandler_t,
);
}
}
extern "C-unwind" fn backtrace_handler(signum: libc::c_int) {
unsafe {
libc::signal(signum, libc::SIG_DFL);
}
let signal_name = match signum {
libc::SIGSEGV => "SIGSEGV (segmentation fault)",
libc::SIGILL => "SIGILL (illegal instruction)",
#[cfg(unix)]
libc::SIGBUS => "SIGBUS (bus error)",
_ => "unknown signal",
};
let bt = std::backtrace::Backtrace::force_capture();
eprintln!("\n*** arf caught fatal signal: {} ***", signal_name);
eprintln!("Backtrace:\n{}", bt);
unsafe {
libc::raise(signum);
}
}