sel4_panicking/
lib.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: BSD-2-Clause
5//
6
7#![no_std]
8#![feature(cfg_target_thread_local)]
9#![feature(core_intrinsics)]
10#![feature(lang_items)]
11#![feature(panic_can_unwind)]
12#![feature(thread_local)]
13#![allow(internal_features)]
14
15#[cfg(feature = "alloc")]
16extern crate alloc;
17
18use core::panic::{PanicInfo, UnwindSafe};
19
20use sel4_panicking_env::{abort, debug_println};
21
22mod count;
23mod hook;
24mod strategy;
25
26use count::{count_panic, count_panic_caught};
27use hook::get_hook;
28
29pub use hook::{PanicHook, set_hook};
30
31#[cfg_attr(feature = "panic-handler", panic_handler)]
32#[cfg_attr(not(feature = "panic-handler"), allow(dead_code))]
33fn panic(info: &PanicInfo) -> ! {
34    if let Some(must_abort) = count_panic() {
35        debug_println!("{}", info);
36        abort!("{}", must_abort);
37    }
38    (get_hook())(info);
39    if info.can_unwind() {
40        let code = strategy::begin_panic();
41        abort!("failed to initiate panic, error {}", code)
42    } else {
43        abort!("can't unwind this panic")
44    }
45}
46
47/// Like `std::panic::catch_unwind`.
48#[allow(clippy::result_unit_err)]
49pub fn catch_unwind<R, F: FnOnce() -> R + UnwindSafe>(f: F) -> Result<R, ()> {
50    strategy::catch_unwind(f).inspect_err(|_| count_panic_caught())
51}
52
53/// Like the unstable `core::panic::abort_unwind`
54pub fn abort_unwind<F, R>(f: F) -> R
55where
56    F: FnOnce() -> R,
57{
58    extern "C" fn wrap<F, R>(f: F) -> R
59    where
60        F: FnOnce() -> R,
61    {
62        f()
63    }
64
65    wrap(f)
66}