Skip to content
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
8 changes: 4 additions & 4 deletions library/std/src/sys/pal/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ pub(crate) fn on_broken_pipe_used() -> bool {
}

// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {
stack_overflow::cleanup();
}
// NOTE: this is not guaranteed to run, for example when the program aborts, and
// is not guaranteed to run on the main thread (#161018 was caused by that
// mistaken assumption).
pub unsafe fn cleanup() {}

#[allow(unused_imports)]
pub use libc::signal;
Expand Down
24 changes: 7 additions & 17 deletions library/std/src/sys/pal/unix/stack_overflow.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![cfg_attr(test, allow(dead_code))]

pub use self::imp::{cleanup, init};
pub use self::imp::init;
use self::imp::{drop_handler, make_handler};

pub struct Handler {
Expand Down Expand Up @@ -143,6 +143,12 @@ mod imp {
}

static PAGE_SIZE: Atomic<usize> = AtomicUsize::new(0);
// Store a pointer to the allocation for the main thread's altstack so that
// tools like valgrind don't complain about a leaked unreachable allocation.
//
// If the main thread exits, the process will terminate so there's no use in
// freeing resources. It also means that the altstack is still installed
// while TLS destructors are run on the main thread (c.f. #111272).
Comment on lines +146 to +151

@clarfonthey clarfonthey Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit: since we can generate private docs these should probably just be doc comments.

View changes since the review

static MAIN_ALTSTACK: Atomic<*mut libc::c_void> = AtomicPtr::new(ptr::null_mut());
static NEED_ALTSTACK: Atomic<bool> = AtomicBool::new(false);

Expand Down Expand Up @@ -190,18 +196,6 @@ mod imp {
}
}

/// # Safety
/// 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)) };

@qwaz qwaz Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than unmapping the main thread's sigalt stack, drop_handler has other side effects like unregistering the current thread's sigalt stack and calling thread_info::delete_current_info. Those should probably be kept?

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code for this, effectively the worst-case scenario here appears to be leaking a Box<str> and maybe a BTreeMap node, which seems pretty minor for an exiting process. I’m also sceptical that this either:

a. isn't called for every thread on exit, leaking memory no matter what, or
b. only called for the exiting thread, which is insufficient

So, this isn't really worth cancelling this change for, but you're welcome to file an issue and propose a separate fix for that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They do seem minor. Thanks for taking a look at this.

}

unsafe fn get_stack() -> libc::stack_t {
// OpenBSD requires this flag for stack mapping
// otherwise the said mapping will fail as a no-op on most systems
Expand Down Expand Up @@ -651,8 +645,6 @@ mod imp {
mod imp {
pub unsafe fn init() {}

pub unsafe fn cleanup() {}

pub unsafe fn make_handler(_main_thread: bool) -> super::Handler {
super::Handler::null()
}
Expand Down Expand Up @@ -735,8 +727,6 @@ mod imp {
reserve_stack();
}

pub unsafe fn cleanup() {}

pub unsafe fn make_handler(main_thread: bool) -> super::Handler {
if !main_thread {
reserve_stack();
Expand Down
4 changes: 3 additions & 1 deletion library/std/src/sys/pal/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {
}

// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
// NOTE: this is not guaranteed to run, for example when the program aborts, and
// is not guaranteed to run on the main thread (#161018 was caused by that
// mistaken assumption).
pub unsafe fn cleanup() {
winsock::cleanup();
}
Expand Down
Loading