Skip to content

Commit 58844ae

Browse files
committed
rt: Make stack unwinding work more correctly with stack growth
1 parent a731f16 commit 58844ae

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

src/rt/rust_task.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ rust_task::~rust_task()
131131
// (ref_count == 1 && this == sched->root_task));
132132

133133
// Delete all the stacks. There may be more than one if the task failed
134+
// FIXME: This is not correct. During unwinding we need to delete
135+
// the stacks and record the stack limit, otherwise the stack
136+
// stack is corrupted when destructors are running.
134137
while (stk != NULL) {
135138
del_stk(this, stk);
136139
}

src/rt/rust_upcall.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ upcall_call_shim_on_c_stack(void *args, void *fn_ptr) {
228228
try {
229229
sched->c_context.call_shim_on_c_stack(args, fn_ptr);
230230
} catch (...) {
231-
//task = rust_scheduler::get_task();
232-
//task->record_stack_limit();
231+
task = rust_scheduler::get_task();
232+
task->record_stack_limit();
233233
throw;
234234
}
235235
task = rust_scheduler::get_task();

src/test/run-fail/morestack2.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// xfail-test
2+
// error-pattern:explicit failure
3+
// compile-flags:--stack-growth
4+
5+
// This time we're testing that the stack limits are restored
6+
// correctly after calling into the C stack and unwinding.
7+
// See the hack in upcall_call_shim_on_c_stack where it messes
8+
// with the stack limit.
9+
10+
native mod rustrt {
11+
fn pin_task();
12+
}
13+
14+
fn getbig_call_c_and_fail(i: int) {
15+
if i != 0 {
16+
getbig_call_c_and_fail(i - 1);
17+
} else {
18+
rustrt::pin_task();
19+
fail;
20+
}
21+
}
22+
23+
resource and_then_get_big_again(_i: ()) {
24+
fn getbig(i: int) {
25+
if i != 0 {
26+
getbig(i - 1);
27+
}
28+
}
29+
getbig(100000);
30+
}
31+
32+
fn main() {
33+
let r = and_then_get_big_again(());
34+
getbig_call_c_and_fail(100000);
35+
}

0 commit comments

Comments
 (0)