Skip to content

Commit be509b3

Browse files
committed
Skip the main thread's manual stack guard on Linux
Linux doesn't allocate the whole stack right away, and the kernel has its own stack-guard mechanism to fault when growing too close to an existing mapping. If we map our own guard, then the kernel starts enforcing a rather large gap above that, rendering much of the possible stack space useless. Instead, we'll just note where we expect rlimit to start faulting, so our handler can report "stack overflow", and trust that the kernel's own stack guard will work. Fixes #43052.
1 parent 7033410 commit be509b3

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

src/libstd/sys/unix/thread.rs

+29-15
Original file line numberDiff line numberDiff line change
@@ -264,23 +264,37 @@ pub mod guard {
264264
as *mut libc::c_void;
265265
}
266266

267-
// Rellocate the last page of the stack.
268-
// This ensures SIGBUS will be raised on
269-
// stack overflow.
270-
let result = mmap(stackaddr, psize, PROT_NONE,
271-
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
272-
273-
if result != stackaddr || result == MAP_FAILED {
274-
panic!("failed to allocate a guard page");
275-
}
276-
277-
let offset = if cfg!(any(target_os = "linux", target_os = "freebsd")) {
278-
2
267+
if cfg!(target_os = "linux") {
268+
// Linux doesn't allocate the whole stack right away, and
269+
// the kernel has its own stack-guard mechanism to fault
270+
// when growing too close to an existing mapping. If we map
271+
// our own guard, then the kernel starts enforcing a rather
272+
// large gap above that, rendering much of the possible
273+
// stack space useless. See #43052.
274+
//
275+
// Instead, we'll just note where we expect rlimit to start
276+
// faulting, so our handler can report "stack overflow", and
277+
// trust that the kernel's own stack guard will work.
278+
Some(stackaddr as usize)
279279
} else {
280-
1
281-
};
280+
// Reallocate the last page of the stack.
281+
// This ensures SIGBUS will be raised on
282+
// stack overflow.
283+
let result = mmap(stackaddr, psize, PROT_NONE,
284+
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
285+
286+
if result != stackaddr || result == MAP_FAILED {
287+
panic!("failed to allocate a guard page");
288+
}
282289

283-
Some(stackaddr as usize + offset * psize)
290+
let offset = if cfg!(target_os = "freebsd") {
291+
2
292+
} else {
293+
1
294+
};
295+
296+
Some(stackaddr as usize + offset * psize)
297+
}
284298
}
285299

286300
#[cfg(target_os = "solaris")]

0 commit comments

Comments
 (0)