diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 2717b7b469cee..11c0a0b9daf7b 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -109,14 +109,14 @@ fn handle_rt_panic(e: Box) -> T { // `compiler/rustc_session/src/config/sigpipe.rs`. #[cfg_attr(test, allow(dead_code))] unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { + // Remember the main thread ID to give it the correct name. + // SAFETY: this is the only time and place where we call this function. + unsafe { main_thread::set(thread::current_id()) }; + #[cfg_attr(target_os = "teeos", allow(unused_unsafe))] unsafe { sys::init(argc, argv, sigpipe) }; - - // Remember the main thread ID to give it the correct name. - // SAFETY: this is the only time and place where we call this function. - unsafe { main_thread::set(thread::current_id()) }; } /// Clean up the thread-local runtime state. This *should* be run after all other diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 226b6bce01b58..040fda75a5080 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -8,8 +8,8 @@ pub struct Handler { } impl Handler { - pub unsafe fn new(thread_name: Option>) -> Handler { - make_handler(false, thread_name) + pub unsafe fn new() -> Handler { + make_handler(false) } fn null() -> Handler { @@ -117,8 +117,15 @@ mod imp { if let Some(thread_info) = thread_info && thread_info.guard_page_range.contains(&fault_addr) { - let name = thread_info.thread_name.as_deref().unwrap_or(""); - let tid = crate::thread::current_os_id(); + // Hey you! Yes, you modifying the stack overflow message! + // Please make sure that all functions called here are + // actually async-signal-safe. If they're not, try retrieving + // the information beforehand and storing it in `ThreadInfo`. + // Thank you! + // - says Jonas after having had to watch his carefully + // written code get made unsound again. + let tid = thread_info.tid; + let name = thread_info.name.as_deref().unwrap_or(""); rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n"); rtabort!("stack overflow"); } @@ -164,12 +171,12 @@ mod imp { if !NEED_ALTSTACK.load(Ordering::Relaxed) { // haven't set up our sigaltstack yet NEED_ALTSTACK.store(true, Ordering::Release); - let handler = unsafe { make_handler(true, None) }; + let handler = unsafe { make_handler(true) }; MAIN_ALTSTACK.store(handler.data, Ordering::Relaxed); mem::forget(handler); if let Some(guard_page_range) = guard_page_range.take() { - set_current_info(guard_page_range, Some(Box::from("main"))); + set_current_info(guard_page_range); } } @@ -240,14 +247,14 @@ mod imp { /// # Safety /// Mutates the alternate signal stack #[forbid(unsafe_op_in_unsafe_fn)] - pub unsafe fn make_handler(main_thread: bool, thread_name: Option>) -> Handler { + pub unsafe fn make_handler(main_thread: bool) -> Handler { if cfg!(panic = "immediate-abort") || !NEED_ALTSTACK.load(Ordering::Acquire) { return Handler::null(); } if !main_thread { if let Some(guard_page_range) = unsafe { current_guard() } { - set_current_info(guard_page_range, thread_name); + set_current_info(guard_page_range); } } @@ -633,10 +640,7 @@ mod imp { pub unsafe fn cleanup() {} - pub unsafe fn make_handler( - _main_thread: bool, - _thread_name: Option>, - ) -> super::Handler { + pub unsafe fn make_handler(_main_thread: bool) -> super::Handler { super::Handler::null() } @@ -720,10 +724,7 @@ mod imp { pub unsafe fn cleanup() {} - pub unsafe fn make_handler( - main_thread: bool, - _thread_name: Option>, - ) -> super::Handler { + pub unsafe fn make_handler(main_thread: bool) -> super::Handler { if !main_thread { reserve_stack(); } diff --git a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs index e81429b98a6c7..42eb0cd9a61af 100644 --- a/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs +++ b/library/std/src/sys/pal/unix/stack_overflow/thread_info.rs @@ -32,8 +32,9 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sys::os::errno_location; pub struct ThreadInfo { + pub tid: u64, + pub name: Option>, pub guard_page_range: Range, - pub thread_name: Option>, } static LOCK: Mutex<()> = Mutex::new(()); @@ -108,14 +109,17 @@ fn spin_lock_in_setup(this: usize) -> UnlockOnDrop { } } -pub fn set_current_info(guard_page_range: Range, thread_name: Option>) { +pub fn set_current_info(guard_page_range: Range) { + let tid = crate::thread::current_os_id(); + let name = crate::thread::with_current_name(|name| name.map(Box::from)); + let this = errno_location().addr(); let _lock_guard = LOCK.lock(); let _spin_guard = spin_lock_in_setup(this); // SAFETY: we own the spin lock, so `THREAD_INFO` cannot be aliased. let thread_info = unsafe { &mut *(&raw mut THREAD_INFO) }; - thread_info.insert(this, ThreadInfo { guard_page_range, thread_name }); + thread_info.insert(this, ThreadInfo { tid, name, guard_page_range }); } pub fn delete_current_info() { diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index d4c27097afd79..4adc94d0e5c9e 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -14,7 +14,7 @@ use crate::sys::weak::dlsym; #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto",))] use crate::sys::weak::weak; use crate::sys::{os, stack_overflow}; -use crate::thread::{ThreadInit, current}; +use crate::thread::ThreadInit; use crate::time::Duration; use crate::{cmp, io, ptr}; #[cfg(not(any( @@ -111,10 +111,9 @@ impl Thread { let init = Box::from_raw(data as *mut ThreadInit); let rust_start = init.init(); - // Set up our thread name and stack overflow handler which may get triggered - // if we run out of stack. - let thread = current(); - let _handler = stack_overflow::Handler::new(thread.name().map(Box::from)); + // Now that the thread information is set, set up our stack + // overflow handler. + let _handler = stack_overflow::Handler::new(); rust_start(); }