Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove segmented stack prelude on Windows #14742

Closed
klutzy opened this issue Jun 8, 2014 · 7 comments
Closed

Remove segmented stack prelude on Windows #14742

klutzy opened this issue Jun 8, 2014 · 7 comments
Labels
O-windows Operating system: Windows

Comments

@klutzy
Copy link
Contributor

klutzy commented Jun 8, 2014

On Windows, stack overflow is detected via two ways:

  1. 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 via VirtualProtect.
  2. 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

@klutzy
Copy link
Contributor Author

klutzy commented Jun 8, 2014

proof-of-concept here. This passes check-stage1-{rpass, rfail, cfail, rmake} and seems to work well?
For end-users, the only change is that the program doesn't print task '<main>' has overflowed its stack message but just dies, and it leaves SIGSEGV instead of SIGILL.

@alexcrichton
Copy link
Member

Note that we are very intentionally still using segmented stacks because we would like the ability to run library code when a task overflows the stack. This is precisely to print that the stack has overflowed, as well as leaving the door open in the future to do something more flavorful.

We would need to figure out how to catch SIGSEGV and print a message or explicitly decide to not have this feature before moving forward with this issue.

@alexcrichton
Copy link
Member

I do agree, however, that I think the segmented stack prelude may be causing more trouble than it's worth now. I suspect, but have never confirmed, that this is not helping FreeBSD by having segmented stacks enabled.

@retep998
Copy link
Member

retep998 commented Jul 9, 2014

By using SEH exceptions handling we'd be able to catch this exact exception and call library code instead of merely causing a SIGSEGV.

@thestinger
Copy link
Contributor

@retep998: LLVM can't really support recovering from a stack overflow. The best it can do is allow you to block the thread forever, because it would be undefined behaviour to unwind from a location it didn't consider as possibly unwinding. It's also impossible to write low-level Rust code that's correct in the presence of unwinding from any function prelude.

@retep998
Copy link
Member

retep998 commented Aug 4, 2014

@thestinger We don't have to unwind. We just have to catch the problem, inform the user that there was a stack overflow somehow (like we do now with a message to stderr), and then kill the program. Using SEH would just make it easy to catch stack overflows on windows without the prelude and without figuring out whether a SIGSEGV was caused by a stackoverflow.

brson added a commit to brson/rust that referenced this issue Sep 26, 2014
bors added a commit that referenced this issue Sep 30, 2014
This is the bare minimum to stop using split stacks on Windows, fixing #13259 and #14742, by turning on stack probes for all functions and disabling compiler and runtime support for split stacks on Windows.

It does not restore the out-of-stack error message, which requires more runtime work.

This includes a test that the Windows TCB is no longer being clobbered, but the out-of-stack test itself is pretty weak, only testing that the program exits abnormally, not that it isn't writing to bogus memory, so I haven't truly verified that this is providing the safety we claim.

A more complete solution is in #16388, which has some unresolved issues yet.

cc @Zoxc @klutzy @vadimcn
@klutzy
Copy link
Contributor Author

klutzy commented Sep 30, 2014

\o/

@klutzy klutzy closed this as completed Sep 30, 2014
bors added a commit to rust-lang-ci/rust that referenced this issue Jun 5, 2023
…kril

feat: Closure capture inlay hints

I opted for a fictional `move(foo, &bar, &mut qux)` syntax here, disabled by default as these are not correct rust syntax and hence could cause confusion.
![image](https://user-images.githubusercontent.com/3757771/236447484-649a4ea6-ad61-496e-bad8-765a5236150e.png)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows
Projects
None yet
Development

No branches or pull requests

5 participants