Skip to main content

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