Skip to main content

panics/
panics.rs

1extern crate psm;
2
3use std::panic;
4
5const CHAIN_DEPTH: usize = 16;
6
7psm::psm_stack_manipulation! {
8    yes {
9        use std::alloc;
10        const STACK_ALIGN: usize = 4096;
11        // Generating backraces (because of RUST_BACKTRACE) create a few quite large frames, so it is
12        // important, that all frames have sufficient amount of available memory to not run over the
13        // stack...
14        const FRAME_SIZE: usize = 4096 * 10;
15
16        fn panic_chain(depth: usize) {
17            if depth == 0 {
18                panic!("full chain!");
19            } else {
20                unsafe {
21                    let layout = alloc::Layout::from_size_align(FRAME_SIZE, STACK_ALIGN).unwrap();
22                    let new_stack = alloc::alloc(layout);
23                    assert!(!new_stack.is_null(), "allocations must succeed!");
24                    let p = psm::on_stack(new_stack, FRAME_SIZE, || {
25                        panic::catch_unwind(|| {
26                            panic_chain(depth - 1);
27                        })
28                    });
29                    alloc::dealloc(new_stack, layout);
30                    p.map_err(panic::resume_unwind).unwrap()
31                }
32            }
33        }
34
35        fn main() {
36            panic_chain(CHAIN_DEPTH);
37        }
38
39        #[test]
40        fn run_example() {
41            assert!(panic::catch_unwind(|| {
42                panic_chain(CHAIN_DEPTH);
43            }).is_err(), "Panic did not propagate!");
44        }
45    }
46
47    no {
48        fn main() {
49            eprintln!("Stack manipulation not supported by this target");
50        }
51    }
52}