miniextendr_api/backtrace.rs
1//! Configurable panic hook for miniextendr-based R packages.
2
3/// This function registers a configurable print panic hook, for use in miniextendr-based R-packages.
4/// If the environment variable `MINIEXTENDR_BACKTRACE` is set to either `true` or `1`,
5/// then it displays the entire Rust panic traceback (default hook), otherwise it omits the panic backtrace.
6#[unsafe(no_mangle)]
7pub extern "C-unwind" fn miniextendr_panic_hook() {
8 static RUN_ONCE: std::sync::Once = std::sync::Once::new();
9 RUN_ONCE.call_once_force(|x| {
10 // On poisoned retry, perform full initialization instead of
11 // returning early. The previous attempt panicked before
12 // completing, so the panic hook may not be installed.
13 if x.is_poisoned() {
14 eprintln!(
15 "warning: miniextendr panic hook is retrying after a previous failed attempt"
16 );
17 }
18 let default_hook = std::panic::take_hook();
19 std::panic::set_hook(Box::new(move |x| {
20 let show_traceback = std::env::var("MINIEXTENDR_BACKTRACE")
21 .map(|v| v.eq_ignore_ascii_case("true") || v == "1")
22 .unwrap_or(false);
23 if show_traceback {
24 default_hook(x)
25 }
26 }));
27 });
28}