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