From 289fe36d373c5a13fa7f1b93f39ff88425ab2351 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 11 Sep 2023 00:59:31 -0400 Subject: Print thread ID in panic message if thread name is unknown `panic!` does not print any identifying information for threads that are unnamed. However, in many cases, the thread ID can be determined. This changes the panic message from something like this: thread '' panicked at src/main.rs:3:5: explicit panic To something like this: thread '' (0xff9bf) panicked at src/main.rs:3:5: explicit panic Stack overflow messages are updated as well. This change applies to both named and unnamed threads. The ID printed is the OS integer thread ID rather than the Rust thread ID, which should also be what debuggers print. --- library/std/src/thread/current.rs | 13 ++++++++++++- library/std/src/thread/mod.rs | 2 +- library/std/src/thread/tests.rs | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'library/std/src/thread') diff --git a/library/std/src/thread/current.rs b/library/std/src/thread/current.rs index 414711298f0..5c879903526 100644 --- a/library/std/src/thread/current.rs +++ b/library/std/src/thread/current.rs @@ -1,4 +1,4 @@ -use super::{Thread, ThreadId}; +use super::{Thread, ThreadId, imp}; use crate::mem::ManuallyDrop; use crate::ptr; use crate::sys::thread_local::local_pointer; @@ -148,6 +148,17 @@ pub(crate) fn current_id() -> ThreadId { id::get_or_init() } +/// Gets the OS thread ID of the thread that invokes it, if available. If not, return the Rust +/// thread ID. +/// +/// We use a `u64` to all possible platform IDs without excess `cfg`; most use `int`, some use a +/// pointer, and Apple uses `uint64_t`. This is a "best effort" approach for diagnostics and is +/// allowed to fall back to a non-OS ID (such as the Rust thread ID) or a non-unique ID (such as a +/// PID) if the thread ID cannot be retrieved. +pub(crate) fn current_os_id() -> u64 { + imp::current_os_id().unwrap_or_else(|| current_id().as_u64().get()) +} + /// Gets a reference to the handle of the thread that invokes it, if the handle /// has been initialized. pub(super) fn try_with_current(f: F) -> R diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 8d3ab82ace1..292323d0118 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -183,7 +183,7 @@ mod current; #[stable(feature = "rust1", since = "1.0.0")] pub use current::current; -pub(crate) use current::{current_id, current_or_unnamed, drop_current}; +pub(crate) use current::{current_id, current_or_unnamed, current_os_id, drop_current}; use current::{set_current, try_with_current}; mod spawnhook; diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 59ec48a57d1..ae889f1e778 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -346,6 +346,13 @@ fn test_thread_id_not_equal() { assert!(thread::current().id() != spawned_id); } +#[test] +fn test_thread_os_id_not_equal() { + let spawned_id = thread::spawn(|| thread::current_os_id()).join().unwrap(); + let current_id = thread::current_os_id(); + assert!(current_id != spawned_id); +} + #[test] fn test_scoped_threads_drop_result_before_join() { let actually_finished = &AtomicBool::new(false); -- cgit 1.4.1-3-g733a5