Skip to content

Commit 3da1046

Browse files
committed
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 '<unnamed>' panicked at src/main.rs:3:5: explicit panic To something like this: thread '<unnamed>' (id 2) panicked at src/main.rs:3:5: explicit panic There is no change in output for named threads or for threads where an ID cannot be determined.
1 parent 9d311f9 commit 3da1046

File tree

7 files changed

+24
-11
lines changed

7 files changed

+24
-11
lines changed

library/std/src/panicking.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -260,15 +260,23 @@ pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path
260260
let msg = match info.payload().downcast_ref::<&'static str>() {
261261
Some(s) => *s,
262262
None => match info.payload().downcast_ref::<String>() {
263-
Some(s) => &s[..],
263+
Some(s) => s.as_str(),
264264
None => "Box<dyn Any>",
265265
},
266266
};
267267
let thread = thread_info::current_thread();
268-
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
269268

270269
let write = |err: &mut dyn crate::io::Write, backtrace: Option<BacktraceStyle>| {
271-
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
270+
let _ = match thread.as_ref().map(|t| t.name().ok_or(t)) {
271+
Some(Ok(name)) => {
272+
writeln!(err, "thread '{name}' panicked at {location}:\n{msg}")
273+
}
274+
Some(Err(t)) => {
275+
let id = t.id().as_u64();
276+
writeln!(err, "thread '<unnamed>' (id {id}) panicked at {location}:\n{msg}",)
277+
}
278+
None => writeln!(err, "thread '<unnamed>' panicked at {location}:\n{msg}"),
279+
};
272280

273281
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
274282

src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//@ignore-target-windows: No libc on Windows
22

33
//@compile-flags: -Zmiri-disable-abi-check
4+
//@normalize-stderr-test: "thread '<unnamed>' \(id [0-9]+\)" -> "thread '<unnamed>'"
45

56
//! Unwinding past the top frame of a stack is Undefined Behavior.
67

src/tools/miri/tests/pass/concurrency/simple.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@compile-flags: -Zmiri-strict-provenance
2+
//@normalize-stderr-test: "thread '<unnamed>' \(id [0-9]+\)" -> "thread '<unnamed>'"
23

34
use std::thread;
45

src/tools/miri/tests/pass/panic/concurrent-panic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// We are making scheduler assumptions here.
22
//@compile-flags: -Zmiri-preemption-rate=0
3+
//@normalize-stderr-test: "thread '<unnamed>' \(id [0-9]+\)" -> "thread '<unnamed>'"
34

45
//! Cause a panic in one thread while another thread is unwinding. This checks
56
//! that separate threads have their own panicking state.
+8-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1+
// Test panic error messages for unnamed threads
2+
13
// run-fail
2-
// error-pattern:thread '<unnamed>' panicked
4+
// regex-error-pattern:thread '<unnamed>' \(id \d+\) panicked
35
// error-pattern:test
46
// ignore-emscripten Needs threads
57

68
use std::thread;
79

810
fn main() {
9-
let r: Result<(), _> = thread::spawn(move || {
10-
panic!("test");
11-
})
12-
.join();
13-
assert!(r.is_ok());
11+
let _: () = thread::spawn(move || {
12+
panic!("test");
13+
})
14+
.join()
15+
.unwrap();
1416
}

tests/ui/proc-macro/load-panic-backtrace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// aux-build:test-macros.rs
22
// compile-flags: -Z proc-macro-backtrace
33
// rustc-env:RUST_BACKTRACE=0
4-
// normalize-stderr-test "thread '.*' panicked " -> ""
4+
// normalize-stderr-test "thread '.*' (\(id \d+\) )?panicked " -> ""
55
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
66
// needs-unwind proc macro panics to report errors
77

tests/ui/process/multi-panic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn check_for_no_backtrace(test: std::process::Output) {
88
let err = String::from_utf8_lossy(&test.stderr);
99
let mut it = err.lines();
1010

11-
assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked")), Some(true));
11+
assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' (id ")), Some(true));
1212
assert_eq!(it.next().is_some(), true);
1313
assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \
1414
environment variable to display a backtrace"));

0 commit comments

Comments
 (0)