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

Avoid panicking unnecessarily on startup #123389

Merged
merged 2 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 11 additions & 19 deletions library/std/src/sys/pal/windows/stack_overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,12 @@
use crate::sys::c;
use crate::thread;

use super::api;

pub struct Handler;

impl Handler {
pub unsafe fn new() -> Handler {
// This API isn't available on XP, so don't panic in that case and just
// pray it works out ok.
if c::SetThreadStackGuarantee(&mut 0x5000) == 0
&& api::get_last_error().code != c::ERROR_CALL_NOT_IMPLEMENTED
{
panic!("failed to reserve stack space for exception handling");
}
Handler
}
/// Reserve stack space for use in stack overflow exceptions.
pub unsafe fn reserve_stack() {
let result = c::SetThreadStackGuarantee(&mut 0x5000);
// Reserving stack space is not critical so we allow it to fail in the released build of libstd.
// We still use debug assert here so that CI will test that we haven't made a mistake calling the function.
debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
}

unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
Expand All @@ -36,9 +27,10 @@ unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POIN
}

pub unsafe fn init() {
if c::AddVectoredExceptionHandler(0, Some(vectored_handler)).is_null() {
panic!("failed to install exception handler");
}
let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler));
// Similar to the above, adding the stack overflow handler is allowed to fail
// but a debug assert is used so CI will still test that it normally works.
debug_assert!(!result.is_null(), "failed to install exception handler");
// Set the thread stack guarantee for the main thread.
let _h = Handler::new();
reserve_stack();
}
9 changes: 1 addition & 8 deletions library/std/src/sys/pal/windows/stack_overflow_uwp.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
#![cfg_attr(test, allow(dead_code))]

pub struct Handler;

impl Handler {
pub fn new() -> Handler {
Handler
}
}

pub unsafe fn reserve_stack() {}
pub unsafe fn init() {}
5 changes: 2 additions & 3 deletions library/std/src/sys/pal/windows/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,8 @@ impl Thread {

extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
unsafe {
// Next, set up our stack overflow handler which may get triggered if we run
// out of stack.
let _handler = stack_overflow::Handler::new();
// Next, reserve some stack space for if we otherwise run out of stack.
stack_overflow::reserve_stack();
// Finally, let's run some code.
Box::from_raw(main as *mut Box<dyn FnOnce()>)();
}
Expand Down
Loading