Skip to main content

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}