Skip to content

Commit 772f380

Browse files
committed
Auto merge of rust-lang#147090 - Noratrieb:immediate-abort-stack-overflow, r=joboet
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) ``` I didn't test the Windows part, but it likely also has savings.
2 parents f957826 + 660a348 commit 772f380

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

library/std/src/sys/pal/unix/stack_overflow.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ mod imp {
148148

149149
let mut guard_page_range = unsafe { install_main_guard() };
150150

151+
// Even for panic=immediate-abort, installing the guard pages is important for soundness.
152+
// That said, we do not care about giving nice stackoverflow messages via our custom
153+
// signal handler, just exit early and let the user enjoy the segfault.
154+
if cfg!(panic = "immediate-abort") {
155+
return;
156+
}
157+
151158
// SAFETY: assuming all platforms define struct sigaction as "zero-initializable"
152159
let mut action: sigaction = unsafe { mem::zeroed() };
153160
for &signal in &[SIGSEGV, SIGBUS] {
@@ -179,6 +186,9 @@ mod imp {
179186
/// Must be called only once
180187
#[forbid(unsafe_op_in_unsafe_fn)]
181188
pub unsafe fn cleanup() {
189+
if cfg!(panic = "immediate-abort") {
190+
return;
191+
}
182192
// FIXME: I probably cause more bugs than I'm worth!
183193
// see https://github.com/rust-lang/rust/issues/111272
184194
unsafe { drop_handler(MAIN_ALTSTACK.load(Ordering::Relaxed)) };
@@ -230,7 +240,7 @@ mod imp {
230240
/// Mutates the alternate signal stack
231241
#[forbid(unsafe_op_in_unsafe_fn)]
232242
pub unsafe fn make_handler(main_thread: bool, thread_name: Option<Box<str>>) -> Handler {
233-
if !NEED_ALTSTACK.load(Ordering::Acquire) {
243+
if cfg!(panic = "immediate-abort") || !NEED_ALTSTACK.load(Ordering::Acquire) {
234244
return Handler::null();
235245
}
236246

library/std/src/sys/pal/windows/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ pub mod os;
2222
pub mod pipe;
2323
pub mod time;
2424
cfg_select! {
25-
not(target_vendor = "uwp") => {
25+
// We don't care about printing nice error messages for panic=immediate-abort
26+
all(not(target_vendor = "uwp"), not(panic = "immediate-abort")) => {
2627
pub mod stack_overflow;
2728
}
2829
_ => {

0 commit comments

Comments
 (0)