From 46164fd07624e11cd0e2afb31901643b8c84493f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 16 Nov 2018 10:32:32 +0100 Subject: [PATCH] Support panics across stack growth boundaries --- src/lib.rs | 7 +++++-- tests/panic_handling.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/panic_handling.rs diff --git a/src/lib.rs b/src/lib.rs index 9420627..833fc8e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,10 +86,13 @@ fn grow_the_stack R>(stack_size: usize, f: F) -> R { let mut ret = None; unsafe { _grow_the_stack(stack_size, &mut || { - ret = Some(f.take().unwrap()()); + ret = Some(std::panic::catch_unwind(std::panic::AssertUnwindSafe(f.take().unwrap()))); }); } - ret.unwrap() + match ret.unwrap() { + Ok(ret) => ret, + Err(payload) => std::panic::resume_unwind(payload), + } } unsafe fn _grow_the_stack(stack_size: usize, mut f: &mut FnMut()) { diff --git a/tests/panic_handling.rs b/tests/panic_handling.rs new file mode 100644 index 0000000..045fa28 --- /dev/null +++ b/tests/panic_handling.rs @@ -0,0 +1,27 @@ +extern crate stacker; + +const RED_ZONE: usize = 100*1024; // 100k +const STACK_PER_RECURSION: usize = 1 * 1024 * 1024; // 1MB + +pub fn ensure_sufficient_stack R + std::panic::UnwindSafe>( + f: F +) -> R { + stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f) +} + +#[inline(never)] +fn recurse(n: usize) { + let x = [42u8; 50000]; + if n == 0 { + panic!("an inconvenient time"); + } else { + ensure_sufficient_stack(|| recurse(n - 1)); + } + drop(x); +} + +#[test] +#[should_panic] +fn foo() { + recurse(10000); +} \ No newline at end of file