Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/edda

crates/nornir-crashlog/examples/crash_probe.rs

// **The deliberate crash.** ONE source file, built under TWO names.
//
// `examples/crash_probe_gpu.rs` is a single `include!` of this file, so the two
// `[[example]]` artifacts are compiled from the same source TEXT and the *only*
// difference between them is `CARGO_BIN_NAME`. That is deliberate: it is
// the dwarves `dwarves-ui` / `dwarves-ui-gpu` shape (two `[[bin]]`s off one `main.rs`)
// reproduced in a crate that builds in seconds, so
// `tests/a_panic_leaves_a_file.rs::two_names_off_one_source_report_two_variants` can
// assert the discriminator without a twenty-minute GUI build.
//
// `argv[1]` picks WHERE the panic happens, because a hook that catches a main-thread
// panic and misses a worker's is a hook that would have missed the measured crash:
//
// * `main`   — panic on the main thread
// * `thread` — panic on a NAMED spawned thread, and let the process die on the join
// * `nested` — panic inside a closure two frames deep on an unnamed thread
// * `clean`  — do not panic at all (the control: no panic ⇒ no file)

fn main() {
    // The variant comes from `CARGO_BIN_NAME`, expanded HERE, in the target being
    // compiled. Nothing else in this file differs between the two artifacts.
    let installed = nornir_crashlog::install_crash_hook!(
        env!("CARGO_PKG_VERSION"),
        // A stand-in for a git sha; the real callers pass their build stamp.
        "probe-build"
    );
    // The startup announcement — printed BEFORE the crash, which is the whole point.
    println!("{}", installed.announce());

    match std::env::args().nth(1).unwrap_or_default().as_str() {
        "main" => panic!("deliberate crash probe: main thread"),
        "thread" => {
            let h = std::thread::Builder::new()
                .name("render-worker".to_string())
                .spawn(|| panic!("deliberate crash probe: non-main thread"))
                .expect("spawn the probe thread");
            // A panicking thread does NOT end the process; the join is what surfaces it.
            // This mirrors an eframe worker: the window stays up and the record is the
            // only trace, which is exactly why the file has to exist.
            let _ = h.join();
            std::process::exit(101);
        }
        "nested" => {
            let h = std::thread::spawn(|| {
                let f = || -> i32 { panic!("deliberate crash probe: nested closure") };
                let g = || f();
                g()
            });
            let _ = h.join();
            std::process::exit(101);
        }
        "clean" => println!("crash-probe: no panic requested"),
        other => {
            eprintln!("crash-probe: unknown mode `{other}` (main|thread|nested|clean)");
            std::process::exit(2);
        }
    }
}