about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-04-04 14:51:17 +0200
committerGitHub <noreply@github.com>2024-04-04 14:51:17 +0200
commitee5009e745b4088f8ef942ab9bcf6f28b7bbac0d (patch)
treee428d24e4b0591aa9b0674a648ab0fbc3a8d7313
parent504a78e2f24a7ce0e11116429c86c0be9553c79c (diff)
parent7b8f93ef4c2b01b6cc7656123301f0f5e322b603 (diff)
downloadrust-ee5009e745b4088f8ef942ab9bcf6f28b7bbac0d.tar.gz
rust-ee5009e745b4088f8ef942ab9bcf6f28b7bbac0d.zip
Rollup merge of #123389 - ChrisDenton:dont-panic-on-startup, r=joboet
Avoid panicking unnecessarily on startup

On Windows, in `lang_start` we add an exception handler to catch stack overflows and we also reserve some stack space for the handler. Both of these are useful but they're not strictly necessary. The standard library has to work without them (e.g. if Rust is used from a foreign entry point) and the negative effect of not doing them is limited (i.e. you don't get the friendly stack overflow message).

As we really don't want to panic pre-main unless absolutely necessary, it now won't panic on failure. I've added some debug assertions so as to avoid programmer error.
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow.rs30
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow_uwp.rs9
-rw-r--r--library/std/src/sys/pal/windows/thread.rs5
3 files changed, 14 insertions, 30 deletions
diff --git a/library/std/src/sys/pal/windows/stack_overflow.rs b/library/std/src/sys/pal/windows/stack_overflow.rs
index 627763da856..f93f31026f8 100644
--- a/library/std/src/sys/pal/windows/stack_overflow.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow.rs
@@ -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 {
@@ -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();
 }
diff --git a/library/std/src/sys/pal/windows/stack_overflow_uwp.rs b/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
index afdf7f566ae..9e9b3efaf1b 100644
--- a/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
@@ -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() {}
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index 80eee4e078d..fe174e1e340 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -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()>)();
             }