Closed
Description
On Windows, stack overflow is detected via two ways:
- Threads have guard page at the end of stack, so it will cause segmentation fault if you try to access guard page.
(To be precise, guard page is set at uncommitted page therefore it detects when to commit page or fail if stack is full).
Green threads also have guard page viaVirtualProtect
. - Guard page is insufficient if a function consumes stack more than page size, thus "jumps" over guard page. To prevent this, Windows compilers add
__chkstk()
or_alloca()
if frame size is greater than 4096. The checker functions tries to access all pages between base pointer and stack pointer.
LLVM also has such support. This is already happening:
$ cat a.rs
#![no_std]
#![crate_type = "lib"]
pub fn large() {
let a = [0u8, ..4096];
}
$ rustc a.rs --target=i686-pc-mingw32 --emit=asm -o a.win.s
__ZN5large20h4dd5255028807332baa4v0.0E::
.cfi_startproc
leal -4104(%esp), %ecx
cmpl %fs:20, %ecx
ja LBB0_0
pushl $0
pushl $4104
calll ___morestack
retl
LBB0_0:
movl $4104, %eax
calll __alloca
...
So we can completely remove __morestack
here and use _alloca
for detection.
Also, currently LLVM uses %fs:0x14
for segmetend stack support, but it seems to break a lot of things: See #13259 and its related issues.
cc #11871