Skip to content

Commit

Permalink
Print thread ID in panic message if thread name is unknown
Browse files Browse the repository at this point in the history
`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:
    message

To something like this:

    thread '<unnamed>' (id 2) panicked at src/main.rs:3:5:
    message

There is no change in output for named threads or for threads where an
ID cannot be determined.
  • Loading branch information
tgross35 committed Sep 11, 2023
1 parent 9d311f9 commit d68fab6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 10 deletions.
12 changes: 10 additions & 2 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,18 @@ pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path
},
};
let thread = thread_info::current_thread();
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");

let write = |err: &mut dyn crate::io::Write, backtrace: Option<BacktraceStyle>| {
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
let _ = match thread.as_ref().map(|t| (t, t.name())) {
Some((_, Some(name))) => {
writeln!(err, "thread '{name}' panicked at {location}:\n{msg}")
}
Some((t, None)) => {
let id = t.id().as_u64();
writeln!(err, "thread '<unnamed>' (id {id}) panicked at {location}:\n{msg}",)
}
None => writeln!(err, "thread '<unnamed>' panicked at {location}:\n{msg}"),
};

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

Expand Down
14 changes: 8 additions & 6 deletions tests/ui/panics/panic-task-name-none.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// Test panic error messages for unnamed threads

// run-fail
// error-pattern:thread '<unnamed>' panicked
// regex-error-pattern:thread '<unnamed>' \(id \d+\) panicked
// error-pattern:test
// ignore-emscripten Needs threads

use std::thread;

fn main() {
let r: Result<(), _> = thread::spawn(move || {
panic!("test");
})
.join();
assert!(r.is_ok());
let _: () = thread::spawn(move || {
panic!("test");
})
.join()
.unwrap();
}
2 changes: 1 addition & 1 deletion tests/ui/proc-macro/load-panic-backtrace.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// aux-build:test-macros.rs
// compile-flags: -Z proc-macro-backtrace
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "thread '.*' panicked " -> ""
// normalize-stderr-test "thread '.*' (\(id \d+\) )?panicked " -> ""
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
// needs-unwind proc macro panics to report errors

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/process/multi-panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn check_for_no_backtrace(test: std::process::Output) {
let err = String::from_utf8_lossy(&test.stderr);
let mut it = err.lines();

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

0 comments on commit d68fab6

Please sign in to comment.