diff options
| author | Noratrieb <48135649+Noratrieb@users.noreply.github.com> | 2025-09-27 13:37:29 +0200 |
|---|---|---|
| committer | Noratrieb <48135649+Noratrieb@users.noreply.github.com> | 2025-09-27 14:16:06 +0200 |
| commit | 660a3486fc6da2c3599a167d73d849178f98bc17 (patch) | |
| tree | da69812eab74491a0ed584d00eea4b5d806b7931 /library | |
| parent | 6f34f4ee074ce0affc7bbf4e2c835f66cd576f13 (diff) | |
| download | rust-660a3486fc6da2c3599a167d73d849178f98bc17.tar.gz rust-660a3486fc6da2c3599a167d73d849178f98bc17.zip | |
Skip stack overflow handler for panic=immediate-abort
std installs guard pages and a signal handler to ensure that stackoverflows 1) terminate abruptly and 2) print an nice message. Even for panic=immediate-abort, 1) is desirable, we don't want silent data corruption there. But 2) is completely unnecessary, as users deliberately *don't* want nice messages, they want minimum binary size. Therefore, skip the entire guard signal handler setup, which saves a lot of bytes. I tested this with a hello world binary using fat LTO, build-std, panic=immediate-abort, opt-level=s, strip=debuginfo. `size` reports significant savings: ``` text data bss dec hex filename 15252 1032 104 16388 4004 tiny-before 6881 964 48 7893 1ed5 tiny-after2 ``` `nm -U` goes from 71 to 56, getting rid of a bunch of stack overflow related symbols. The disk size goes from `31k` to `24k`. The impact on the error message is minimal, as the message was already missing. before: ``` fish: Job 1, './tiny-so-before' terminated by signal SIGABRT (Abort) ``` after: ``` fish: Job 1, './tiny-so-after' terminated by signal SIGSEGV (Address boundary error) ```
Diffstat (limited to 'library')
| -rw-r--r-- | library/std/src/sys/pal/unix/stack_overflow.rs | 12 | ||||
| -rw-r--r-- | library/std/src/sys/pal/windows/mod.rs | 3 |
2 files changed, 13 insertions, 2 deletions
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 0d2100d66bc..08a3cee64ba 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -148,6 +148,13 @@ mod imp { let mut guard_page_range = unsafe { install_main_guard() }; + // Even for panic=immediate-abort, installing the guard pages is important for soundness. + // That said, we do not care about giving nice stackoverflow messages via our custom + // signal handler, just exit early and let the user enjoy the segfault. + if cfg!(panic = "immediate-abort") { + return; + } + // SAFETY: assuming all platforms define struct sigaction as "zero-initializable" let mut action: sigaction = unsafe { mem::zeroed() }; for &signal in &[SIGSEGV, SIGBUS] { @@ -179,6 +186,9 @@ mod imp { /// Must be called only once #[forbid(unsafe_op_in_unsafe_fn)] pub unsafe fn cleanup() { + if cfg!(panic = "immediate-abort") { + return; + } // FIXME: I probably cause more bugs than I'm worth! // see https://github.com/rust-lang/rust/issues/111272 unsafe { drop_handler(MAIN_ALTSTACK.load(Ordering::Relaxed)) }; @@ -230,7 +240,7 @@ mod imp { /// Mutates the alternate signal stack #[forbid(unsafe_op_in_unsafe_fn)] pub unsafe fn make_handler(main_thread: bool, thread_name: Option<Box<str>>) -> Handler { - if !NEED_ALTSTACK.load(Ordering::Acquire) { + if cfg!(panic = "immediate-abort") || !NEED_ALTSTACK.load(Ordering::Acquire) { return Handler::null(); } diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 3357946b8f7..b7578b01584 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -22,7 +22,8 @@ pub mod os; pub mod pipe; pub mod time; cfg_select! { - not(target_vendor = "uwp") => { + // We don't care about printing nice error messages for panic=immediate-abort + all(not(target_vendor = "uwp"), not(panic = "immediate-abort")) => { pub mod stack_overflow; } _ => { |
