Skip to content

Commit e0ff0e9

Browse files
committed
---
yaml --- r: 11651 b: refs/heads/master c: cc276fe h: refs/heads/master i: 11649: 57acfff 11647: 38dffe5 v: v3
1 parent ce8df5d commit e0ff0e9

File tree

4 files changed

+24
-6
lines changed

4 files changed

+24
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: c78da1e17016d178d55d5f899ab254f5ed44a899
2+
refs/heads/master: cc276fe3c96965ba39b9fba3b588a1eaa3941d86
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rt/rust_stack.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ register_valgrind_stack(stk_seg *stk) {
1717
}
1818

1919
void
20-
prepare_valgrind_stack(stk_seg *stk) {
20+
reuse_valgrind_stack(stk_seg *stk, uint8_t *sp) {
2121
#ifndef NVALGRIND
2222
// Establish that the stack is accessible. This must be done when reusing
2323
// old stack segments, since the act of popping the stack previously
2424
// caused valgrind to consider the whole thing inaccessible.
25-
size_t sz = stk->end - (uintptr_t)&stk->data[0];
26-
VALGRIND_MAKE_MEM_UNDEFINED(stk->data, sz);
25+
assert(sp >= stk->data && sp <= (uint8_t*) stk->end
26+
&& "Stack pointer must be inside stack segment");
27+
size_t sz = stk->end - (uintptr_t)sp;
28+
VALGRIND_MAKE_MEM_UNDEFINED(sp, sz);
2729
#endif
2830
}
2931

trunk/src/rt/rust_stack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ destroy_stack(memory_region *region, stk_seg *stk);
2626
// Must be called before each time a stack is reused to tell valgrind
2727
// that the stack is accessible.
2828
void
29-
prepare_valgrind_stack(stk_seg *stk);
29+
reuse_valgrind_stack(stk_seg *stk, uint8_t *sp);
3030

3131
// Run a sanity check
3232
void

trunk/src/rt/rust_task.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,6 @@ rust_task::new_stack(size_t requested_sz) {
571571
LOG(this, mem, "reusing existing stack");
572572
stk = stk->prev;
573573
A(thread, stk->prev == NULL, "Bogus stack ptr");
574-
prepare_valgrind_stack(stk);
575574
return;
576575
} else {
577576
LOG(this, mem, "existing stack is not big enough");
@@ -637,12 +636,29 @@ rust_task::del_stack() {
637636

638637
void *
639638
rust_task::next_stack(size_t stk_sz, void *args_addr, size_t args_sz) {
639+
stk_seg *maybe_next_stack = NULL;
640+
if (stk != NULL) {
641+
maybe_next_stack = stk->prev;
642+
}
643+
640644
new_stack(stk_sz + args_sz);
641645
A(thread, stk->end - (uintptr_t)stk->data >= stk_sz + args_sz,
642646
"Did not receive enough stack");
643647
uint8_t *new_sp = (uint8_t*)stk->end;
644648
// Push the function arguments to the new stack
645649
new_sp = align_down(new_sp - args_sz);
650+
651+
// When reusing a stack segment we need to tell valgrind that this area of
652+
// memory is accessible before writing to it, because the act of popping
653+
// the stack previously made all of the stack inaccessible.
654+
if (maybe_next_stack == stk) {
655+
// I don't know exactly where the region ends that valgrind needs us
656+
// to mark accessible. On x86_64 these extra bytes aren't needed, but
657+
// on i386 we get errors without.
658+
int fudge_bytes = 16;
659+
reuse_valgrind_stack(stk, new_sp - fudge_bytes);
660+
}
661+
646662
memcpy(new_sp, args_addr, args_sz);
647663
A(thread, rust_task_thread::get_task() == this,
648664
"Recording the stack limit for the wrong thread");

0 commit comments

Comments
 (0)