auto merge of #8217 : brson/rust/reset_stack_limit, r=pcwalton
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.
This commit is contained in:
commit
91b711883c
2 changed files with 13 additions and 1 deletions
|
@ -609,10 +609,21 @@ when unwinding through __morestack).
|
||||||
void
|
void
|
||||||
rust_task::reset_stack_limit() {
|
rust_task::reset_stack_limit() {
|
||||||
uintptr_t sp = get_sp();
|
uintptr_t sp = get_sp();
|
||||||
|
bool reseted = false;
|
||||||
while (!sp_in_stk_seg(sp, stk)) {
|
while (!sp_in_stk_seg(sp, stk)) {
|
||||||
|
reseted = true;
|
||||||
prev_stack();
|
prev_stack();
|
||||||
assert(stk != NULL && "Failed to find the current 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
|
void
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// xfail-test
|
// xfail-fast
|
||||||
|
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
|
||||||
use std::comm::*;
|
use std::comm::*;
|
||||||
|
|
Loading…
Reference in a new issue