Skip to main content

edgefirst_tensor/
covguard.rs

1// SPDX-FileCopyrightText: Copyright 2025 Au-Zone Technologies
2// SPDX-License-Identifier: Apache-2.0
3
4//! Coverage-capture resilience for crash-on-shutdown hardware (e.g. the i.MX
5//! Vivante EGL driver SIGABRTs during teardown after tests pass). Under
6//! coverage instrumentation only, install a SIGABRT handler that flushes the
7//! LLVM profile to LLVM_PROFILE_FILE *before* the abort completes, then
8//! restores the default disposition and re-raises so the process exit status
9//! is unchanged (the CI workflow already treats JUnit as the source of truth).
10//!
11//! No-op unless built with `-Cinstrument-coverage` (the `coverage` cfg, set by
12//! build.rs) on Linux. Never installed in shipped release builds.
13
14/// Install the coverage flush-on-abort handler. Idempotent; safe to call from
15/// multiple artifact constructors. No-op outside instrumented Linux builds.
16pub fn install() {
17    #[cfg(all(coverage, target_os = "linux"))]
18    {
19        use std::sync::Once;
20        static ONCE: Once = Once::new();
21        ONCE.call_once(|| unsafe {
22            libc::signal(
23                libc::SIGABRT,
24                flush_then_reraise as extern "C" fn(libc::c_int) as libc::sighandler_t,
25            );
26        });
27    }
28}
29
30#[cfg(all(coverage, target_os = "linux"))]
31extern "C" fn flush_then_reraise(_sig: libc::c_int) {
32    extern "C" {
33        // Provided by the LLVM profiling runtime under -Cinstrument-coverage.
34        fn __llvm_profile_write_file() -> libc::c_int;
35    }
36    // SAFETY: async-signal context. The profile writer is the established
37    // crash-coverage path; signal()/raise() are async-signal-safe. Best-effort:
38    // the heap may already be corrupt, but this is strictly better than losing
39    // all coverage. We do NOT _exit(0) — re-raising preserves the exit status.
40    unsafe {
41        __llvm_profile_write_file();
42        libc::signal(libc::SIGABRT, libc::SIG_DFL);
43        libc::raise(libc::SIGABRT);
44    }
45}