Skip to content
Merged
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
56 changes: 35 additions & 21 deletions library/std/src/sys/pal/unix/stack_overflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,15 @@ cfg_select! {
// usually have fewer qualms about forwards compatibility, since the runtime
// is shipped with the OS):
// <https://github.com/apple/swift/blob/swift-5.10-RELEASE/stdlib/public/runtime/CrashHandlerMacOS.cpp>
//
// miri doesn't model signals nor stack overflows and this code has some
// synchronization properties that we don't want to expose to user code,
// hence we disable it on miri.
all(
not(miri),
any(
target_os = "linux",
target_os = "freebsd",
target_os = "hurd",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
)
any(
target_os = "linux",
target_os = "freebsd",
target_os = "hurd",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "solaris",
target_os = "illumos",
) => {
mod handler_signal;
mod thread_info;
Expand All @@ -41,16 +34,33 @@ cfg_select! {
}
}

pub use self::imp::init;
use self::imp::{drop_handler, make_handler};
/// # Safety
/// Must be called only once, on the main thread, during program startup.
pub unsafe fn init() {
// miri doesn't model signals nor stack overflows and this code has some
// synchronization properties that we don't want to expose to user code,
// hence we disable it on miri.
if cfg!(miri) {
return;
}

// SAFETY: guaranteed by caller.
unsafe { imp::init() };
}

pub struct Handler {
data: *mut libc::c_void,
}

impl Handler {
pub unsafe fn new() -> Handler {
make_handler(false)
// The stack overflow detection logic, even if disabled, has some
// synchronization logic that should be disabled under miri.
if cfg!(miri) {
return Handler::null();
}

@RalfJung RalfJung Oct 4, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A comment similar to above would be good.

View changes since the review


imp::make_handler(false)
}

fn null() -> Handler {
Expand All @@ -60,8 +70,12 @@ impl Handler {

impl Drop for Handler {
fn drop(&mut self) {
unsafe {
drop_handler(self.data);
// The stack overflow detection logic, even if disabled, has some
// synchronization logic that should be disabled under miri.
if cfg!(miri) {
return;
}
Comment on lines +75 to 77

@RalfJung RalfJung Oct 4, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't the existing handler already required to be sound on a null pointer? Why does Miri need a special check?

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

drop_handler unconditionally accesses the thread information BTreeMap, which means there is some extra synchronisation – enough to make some miri tests fail.


unsafe { imp::drop_handler(self.data) };
}
}
Loading