about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-04-09 15:54:51 -0700
committerBrian Anderson <banderson@mozilla.com>2012-04-09 16:03:06 -0700
commit596376ea55256ddea22afd2d854438c23075b592 (patch)
treea51a261820edb6f2c7e43c89a3ae0f5a404b36cc /src
parentb42c6d07dc4b1aeb66901bd29b14ab34f9ef1183 (diff)
downloadrust-596376ea55256ddea22afd2d854438c23075b592.tar.gz
rust-596376ea55256ddea22afd2d854438c23075b592.zip
rt: Allow 2x normal stack during unwinding. Closes #2173
Allows room for destructors to run without allowing the stack to grow forever.
Diffstat (limited to 'src')
-rw-r--r--src/rt/rust_task.cpp24
-rw-r--r--src/test/run-fail/too-much-recursion-unwinding.rs23
2 files changed, 35 insertions, 12 deletions
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