From 596376ea55256ddea22afd2d854438c23075b592 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 9 Apr 2012 15:54:51 -0700 Subject: [PATCH] rt: Allow 2x normal stack during unwinding. Closes #2173 Allows room for destructors to run without allowing the stack to grow forever. --- src/rt/rust_task.cpp | 24 +++++++++---------- .../run-fail/too-much-recursion-unwinding.rs | 23 ++++++++++++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 src/test/run-fail/too-much-recursion-unwinding.rs diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index b0ced523390..b4c38de99e7 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -512,19 +512,19 @@ rust_task::new_stack(size_t requested_sz) { size_t rust_stk_sz = get_next_stack_size(min_sz, current_sz, requested_sz); - if (total_stack_sz + rust_stk_sz > kernel->env->max_stack_size) { + size_t max_stack = kernel->env->max_stack_size; + size_t used_stack = total_stack_sz + rust_stk_sz; + + // Don't allow stacks to grow forever. During unwinding we have to allow + // for more stack than normal in order to allow destructors room to run, + // arbitrarily selected as 2x the maximum stack size. + if (!unwinding && used_stack > max_stack) { LOG_ERR(this, task, "task %" PRIxPTR " ran out of stack", this); - if (!unwinding) { - fail(); - } else { - // FIXME: Because we have landing pads that may need more - // stack than normally allowed we have to go allow the stack - // to grow unbounded during unwinding. Would be nice to - // have a different solution - maybe just double the limit. - LOG_ERR(this, task, "task %" PRIxPTR " has blown its stack " - "budget but we are unwinding so growing the stack " - "anyway"); - } + fail(); + } else if (unwinding && used_stack > max_stack) { + LOG_ERR(this, task, + "task %" PRIxPTR " ran out of stack during unwinding", this); + fail(); } size_t sz = rust_stk_sz + RED_ZONE_SIZE; diff --git a/src/test/run-fail/too-much-recursion-unwinding.rs b/src/test/run-fail/too-much-recursion-unwinding.rs new file mode 100644 index 00000000000..e56361e2f72 --- /dev/null +++ b/src/test/run-fail/too-much-recursion-unwinding.rs @@ -0,0 +1,23 @@ +// error-pattern:ran out of stack +// xfail-test - right now we leak when we fail during failure + +// Test that the task fails after hiting the recursion limit +// durnig unwinding + +fn recurse() { + log(debug, "don't optimize me out"); + recurse(); +} + +resource r(recursed: *mut bool) unsafe { + if !*recursed { + *recursed = true; + recurse(); + } +} + +fn main() { + let mut recursed = false; + let _r = r(ptr::mut_addr_of(recursed)); + recurse(); +} \ No newline at end of file