]> git.lizzy.rs Git - rust.git/commitdiff
rt: Fix a corner-case in unwinding that leads to stack overflow
authorBrian Anderson <banderson@mozilla.com>
Fri, 2 Aug 2013 04:14:43 +0000 (21:14 -0700)
committerBrian Anderson <banderson@mozilla.com>
Sun, 4 Aug 2013 06:40:25 +0000 (23:40 -0700)
In some scenarios upcall_rust_stack_limit fails to record the stack
limit, leaving it 0, and allowing subsequent Rust code to run into
the red zone.

src/rt/rust_task.cpp
src/test/run-pass/unwind-resource.rs

index 72979d67eefc86ff7612ef7b6e33d5eacffccb78..2f6b8acb0725c3c12996f5c08a7b6d0991ab3af8 100644 (file)
@@ -609,10 +609,21 @@ when unwinding through __morestack).
 void
 rust_task::reset_stack_limit() {
     uintptr_t sp = get_sp();
+    bool reseted = false;
     while (!sp_in_stk_seg(sp, stk)) {
+        reseted = true;
         prev_stack();
         assert(stk != NULL && "Failed to find the current stack");
     }
+
+    // Each call to prev_stack will record the stack limit. If we *didn't*
+    // call prev_stack then we still need to record it now to catch a corner case:
+    // the throw to initiate unwinding starts on the C stack while sp limit is 0.
+    // If we don't set the limit here then the rust code run subsequently will
+    // will veer into the red zone. Lame!
+    if (!reseted) {
+        record_stack_limit();
+    }
 }
 
 void
index a36be079b43434e9e2cbe2eaf927704f6e74aff9..bde90e3726ed3d7fdc45bcbf4d3fdf96cbbaf30a 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
+// xfail-fast
+
 extern mod extra;
 
 use std::comm::*;