1#![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#[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
51pub 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}