about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2023-09-11 00:59:31 -0400
committerTrevor Gross <tmgross@umich.edu>2025-08-06 23:59:47 +0000
commit289fe36d373c5a13fa7f1b93f39ff88425ab2351 (patch)
tree410435fc6fa49a1ffd25c9e52e579087ed639c5e
parent0c8b3870bd9ec60093b478b318858fdb220846b7 (diff)
downloadrust-289fe36d373c5a13fa7f1b93f39ff88425ab2351.tar.gz
rust-289fe36d373c5a13fa7f1b93f39ff88425ab2351.zip
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>' (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.
-rw-r--r--library/std/src/panicking.rs3
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs4
-rw-r--r--library/std/src/sys/pal/itron/thread.rs4
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs6
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs4
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs4
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs6
-rw-r--r--library/std/src/sys/pal/unix/thread.rs56
-rw-r--r--library/std/src/sys/pal/unsupported/thread.rs4
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs4
-rw-r--r--library/std/src/sys/pal/windows/c/bindings.txt1
-rw-r--r--library/std/src/sys/pal/windows/c/windows_sys.rs1
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow.rs3
-rw-r--r--library/std/src/sys/pal/windows/thread.rs8
-rw-r--r--library/std/src/sys/pal/xous/thread.rs4
-rw-r--r--library/std/src/thread/current.rs13
-rw-r--r--library/std/src/thread/mod.rs2
-rw-r--r--library/std/src/thread/tests.rs7
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr4
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr2
-rw-r--r--src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/abort_unwind.stderr4
-rw-r--r--src/tools/miri/tests/fail/panic/bad_unwind.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/double_panic.stderr6
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort1.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort2.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort3.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/panic_abort4.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr2
-rw-r--r--src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr2
-rw-r--r--src/tools/miri/tests/fail/terminate-terminator.stderr4
-rw-r--r--src/tools/miri/tests/fail/unwind-action-terminate.stderr4
-rw-r--r--src/tools/miri/tests/panic/alloc_error_handler_hook.stderr2
-rw-r--r--src/tools/miri/tests/panic/alloc_error_handler_panic.stderr2
-rw-r--r--src/tools/miri/tests/panic/div-by-zero-2.stderr2
-rw-r--r--src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr6
-rw-r--r--src/tools/miri/tests/panic/mir-validation.rs6
-rw-r--r--src/tools/miri/tests/panic/mir-validation.stderr2
-rw-r--r--src/tools/miri/tests/panic/oob_subslice.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-lsh-neg.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-rsh-1.stderr2
-rw-r--r--src/tools/miri/tests/panic/overflowing-rsh-2.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic1.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic2.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic3.stderr2
-rw-r--r--src/tools/miri/tests/panic/panic4.stderr2
-rw-r--r--src/tools/miri/tests/panic/transmute_fat2.stderr2
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.stderr22
-rw-r--r--src/tools/miri/tests/pass/panic/concurrent-panic.stderr4
-rw-r--r--src/tools/miri/tests/pass/panic/nested_panic_caught.stderr4
-rw-r--r--src/tools/miri/tests/pass/panic/thread_panic.stderr4
-rw-r--r--src/tools/rustfmt/tests/rustfmt/main.rs3
-rw-r--r--tests/run-make/libtest-json/output-default.json2
-rw-r--r--tests/run-make/libtest-json/output-stdout-success.json4
-rw-r--r--tests/run-make/libtest-json/rmake.rs1
-rw-r--r--tests/run-make/libtest-junit/output-default.xml2
-rw-r--r--tests/run-make/libtest-junit/output-stdout-success.xml2
-rw-r--r--tests/run-make/libtest-junit/rmake.rs1
-rw-r--r--tests/rustdoc-ui/doctest/edition-2024-error-output.stdout2
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout2
-rw-r--r--tests/rustdoc-ui/doctest/failed-doctest-output.stdout2
-rw-r--r--tests/rustdoc-ui/doctest/stdout-and-stderr.stdout4
-rw-r--r--tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout2
-rw-r--r--tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs2
-rw-r--r--tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs2
-rw-r--r--tests/ui/backtrace/synchronized-panic-handler.run.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-80742.rs2
-rw-r--r--tests/ui/extern/extern-types-field-offset.run.stderr2
-rw-r--r--tests/ui/extern/extern-types-size_of_val.align.run.stderr2
-rw-r--r--tests/ui/extern/extern-types-size_of_val.size.run.stderr2
-rw-r--r--tests/ui/hygiene/panic-location.run.stderr2
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace.run.stderr2
-rw-r--r--tests/ui/intrinsics/not-overridden.rs2
-rw-r--r--tests/ui/issues/issue-87707.run.stderr4
-rw-r--r--tests/ui/layout/valid_range_oob.rs2
-rw-r--r--tests/ui/macros/assert-long-condition.run.stderr2
-rw-r--r--tests/ui/mir/lint/storage-live.rs2
-rw-r--r--tests/ui/nll/issue-51345-2.rs4
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-add.rs4
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-mul.rs4
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-pow-signed.rs4
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-pow-unsigned.rs4
-rw-r--r--tests/ui/numbers-arithmetic/overflowing-sub.rs4
-rw-r--r--tests/ui/panics/fmt-only-once.run.stderr2
-rw-r--r--tests/ui/panics/issue-47429-short-backtraces.run.stderr2
-rw-r--r--tests/ui/panics/location-detail-panic-no-column.run.stderr2
-rw-r--r--tests/ui/panics/location-detail-panic-no-file.run.stderr2
-rw-r--r--tests/ui/panics/location-detail-panic-no-line.run.stderr2
-rw-r--r--tests/ui/panics/location-detail-panic-no-location-info.run.stderr2
-rw-r--r--tests/ui/panics/location-detail-unwrap-no-file.run.stderr2
-rw-r--r--tests/ui/panics/main-panic.rs2
-rw-r--r--tests/ui/panics/panic-in-cleanup.run.stderr6
-rw-r--r--tests/ui/panics/panic-in-ffi.run.stderr4
-rw-r--r--tests/ui/panics/panic-set-unset-handler.rs4
-rw-r--r--tests/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr2
-rw-r--r--tests/ui/panics/panic-take-handler-nop.rs4
-rw-r--r--tests/ui/panics/panic-task-name-none.rs10
-rw-r--r--tests/ui/panics/panic-task-name-owned.rs20
-rw-r--r--tests/ui/panics/runtime-switch.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.run.stderr2
-rw-r--r--tests/ui/proc-macro/load-panic-backtrace.rs2
-rw-r--r--tests/ui/proc-macro/load-panic-backtrace.stderr2
-rw-r--r--tests/ui/process/multi-panic.rs21
-rw-r--r--tests/ui/process/println-with-broken-pipe.run.stderr2
-rw-r--r--tests/ui/resolve/multiple_definitions_attribute_merging.rs2
-rw-r--r--tests/ui/resolve/proc_macro_generated_packed.rs2
-rw-r--r--tests/ui/test-attrs/terse.run.stdout6
-rw-r--r--tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr4
-rw-r--r--tests/ui/test-attrs/test-panic-abort.run.stdout2
-rw-r--r--tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr8
-rw-r--r--tests/ui/test-attrs/test-thread-capture.run.stdout2
-rw-r--r--tests/ui/test-attrs/test-thread-nocapture.run.stderr2
-rw-r--r--tests/ui/track-diagnostics/track.rs5
-rw-r--r--tests/ui/track-diagnostics/track.stderr2
-rw-r--r--tests/ui/treat-err-as-bug/err.rs2
-rw-r--r--tests/ui/treat-err-as-bug/span_delayed_bug.rs2
-rw-r--r--tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs2
122 files changed, 311 insertions, 168 deletions
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 224cd39855a..547906ca7dc 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -269,6 +269,7 @@ fn default_hook(info: &PanicHookInfo<'_>) {
 
         thread::with_current_name(|name| {
             let name = name.unwrap_or("<unnamed>");
+            let tid = thread::current_os_id();
 
             // Try to write the panic message to a buffer first to prevent other concurrent outputs
             // interleaving with it.
@@ -277,7 +278,7 @@ fn default_hook(info: &PanicHookInfo<'_>) {
 
             let write_msg = |dst: &mut dyn crate::io::Write| {
                 // We add a newline to ensure the panic message appears at the start of a line.
-                writeln!(dst, "\nthread '{name}' panicked at {location}:\n{msg}")
+                writeln!(dst, "\nthread '{name}' ({tid}) panicked at {location}:\n{msg}")
             };
 
             if write_msg(&mut cursor).is_ok() {
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 95fe4f902d3..cc4734b6819 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -115,6 +115,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsafe { Ok(NonZero::new_unchecked(hermit_abi::available_parallelism())) }
 }
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index 0d28051fcc4..4e14cb3cbca 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -361,6 +361,10 @@ unsafe fn terminate_and_delete_current_task() -> ! {
     unsafe { crate::hint::unreachable_unchecked() };
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     super::unsupported()
 }
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index a236c362706..1f613badcd7 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -1,6 +1,6 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
 
-use super::abi::usercalls;
+use super::abi::{thread, usercalls};
 use super::unsupported;
 use crate::ffi::CStr;
 use crate::io;
@@ -149,6 +149,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    Some(thread::current().addr().get() as u64)
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index a91d95626e7..1812d11e692 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -144,6 +144,10 @@ impl Drop for Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 // Note: Both `sched_getaffinity` and `sysconf` are available but not functional on
 // teeos, so this function always returns an Error!
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
index 75c364362b2..47a48008c76 100644
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -56,6 +56,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // UEFI is single threaded
     Ok(NonZero::new(1).unwrap())
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index d89100e6919..0d2100d66bc 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -119,7 +119,8 @@ mod imp {
                     && thread_info.guard_page_range.contains(&fault_addr)
                 {
                     let name = thread_info.thread_name.as_deref().unwrap_or("<unknown>");
-                    rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                    let tid = crate::thread::current_os_id();
+                    rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
                     rtabort!("stack overflow");
                 }
             })
@@ -696,7 +697,8 @@ mod imp {
             if code == c::EXCEPTION_STACK_OVERFLOW {
                 crate::thread::with_current_name(|name| {
                     let name = name.unwrap_or("<unknown>");
-                    rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                    let tid = crate::thread::current_os_id();
+                    rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
                 });
             }
             c::EXCEPTION_CONTINUE_SEARCH
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7f6440152d4..36e53e7cadc 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -398,6 +398,62 @@ impl Drop for Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    // Most Unix platforms have a way to query an integer ID of the current thread, all with
+    // slightly different spellings.
+    //
+    // The OS thread ID is used rather than `pthread_self` so as to match what will be displayed
+    // for process inspection (debuggers, trace, `top`, etc.).
+    cfg_if::cfg_if! {
+        // Most platforms have a function returning a `pid_t` or int, which is an `i32`.
+        if #[cfg(any(target_os = "android", target_os = "linux"))] {
+            use crate::sys::weak::syscall;
+
+            // `libc::gettid` is only available on glibc 2.30+, but the syscall is available
+            // since Linux 2.4.11.
+            syscall!(fn gettid() -> libc::pid_t;);
+
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { gettid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "nto")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::gettid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "openbsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pid_t = unsafe { libc::getthrid() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "freebsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::c_int = unsafe { libc::pthread_getthreadid_np() };
+            Some(id as u64)
+        } else if #[cfg(target_os = "netbsd")] {
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::lwpid_t = unsafe { libc::_lwp_self() };
+            Some(id as u64)
+        } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
+            // On Illumos and Solaris, the `pthread_t` is the same as the OS thread ID.
+            // SAFETY: FFI call with no preconditions.
+            let id: libc::pthread_t = unsafe { libc::pthread_self() };
+            Some(id as u64)
+        } else if #[cfg(target_vendor = "apple")] {
+            // Apple allows querying arbitrary thread IDs, `thread=NULL` queries the current thread.
+            let mut id = 0u64;
+            // SAFETY: `thread_id` is a valid pointer, no other preconditions.
+            let status: libc::c_int = unsafe { libc::pthread_threadid_np(0, &mut id) };
+            if status == 0 {
+                Some(id)
+            } else {
+                None
+            }
+        } else {
+            // Other platforms don't have an OS thread ID or don't have a way to access it.
+            None
+        }
+    }
+}
+
 #[cfg(any(
     target_os = "linux",
     target_os = "nto",
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index 5a1e3fde986..34d9b5ec70c 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/pal/unsupported/thread.rs
@@ -39,6 +39,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     unsupported()
 }
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index a46c74630c9..4755e2ef5da 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -194,6 +194,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     cfg_if::cfg_if! {
         if #[cfg(target_feature = "atomics")] {
diff --git a/library/std/src/sys/pal/windows/c/bindings.txt b/library/std/src/sys/pal/windows/c/bindings.txt
index 827d96e73db..c8e4dca4781 100644
--- a/library/std/src/sys/pal/windows/c/bindings.txt
+++ b/library/std/src/sys/pal/windows/c/bindings.txt
@@ -2185,6 +2185,7 @@ GetSystemInfo
 GetSystemTimeAsFileTime
 GetSystemTimePreciseAsFileTime
 GetTempPathW
+GetThreadId
 GetUserProfileDirectoryW
 GetWindowsDirectoryW
 HANDLE
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index b2e3aabc633..45a273d241a 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -61,6 +61,7 @@ windows_targets::link!("kernel32.dll" "system" fn GetSystemInfo(lpsysteminfo : *
 windows_targets::link!("kernel32.dll" "system" fn GetSystemTimeAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
 windows_targets::link!("kernel32.dll" "system" fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime : *mut FILETIME));
 windows_targets::link!("kernel32.dll" "system" fn GetTempPathW(nbufferlength : u32, lpbuffer : PWSTR) -> u32);
+windows_targets::link!("kernel32.dll" "system" fn GetThreadId(thread : HANDLE) -> u32);
 windows_targets::link!("userenv.dll" "system" fn GetUserProfileDirectoryW(htoken : HANDLE, lpprofiledir : PWSTR, lpcchsize : *mut u32) -> BOOL);
 windows_targets::link!("kernel32.dll" "system" fn GetWindowsDirectoryW(lpbuffer : PWSTR, usize : u32) -> u32);
 windows_targets::link!("kernel32.dll" "system" fn InitOnceBeginInitialize(lpinitonce : *mut INIT_ONCE, dwflags : u32, fpending : *mut BOOL, lpcontext : *mut *mut core::ffi::c_void) -> BOOL);
diff --git a/library/std/src/sys/pal/windows/stack_overflow.rs b/library/std/src/sys/pal/windows/stack_overflow.rs
index 734cd30bed0..9a40551b985 100644
--- a/library/std/src/sys/pal/windows/stack_overflow.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow.rs
@@ -20,7 +20,8 @@ unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POIN
         if code == c::EXCEPTION_STACK_OVERFLOW {
             thread::with_current_name(|name| {
                 let name = name.unwrap_or("<unknown>");
-                rtprintpanic!("\nthread '{name}' has overflowed its stack\n");
+                let tid = thread::current_os_id();
+                rtprintpanic!("\nthread '{name}' ({tid}) has overflowed its stack\n");
             });
         }
         c::EXCEPTION_CONTINUE_SEARCH
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index b45f76fb546..c708da5af12 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -127,6 +127,14 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    // SAFETY: FFI call with no preconditions.
+    let id: u32 = unsafe { c::GetThreadId(c::GetCurrentThread()) };
+
+    // A return value of 0 indicates failed lookup.
+    if id == 0 { None } else { Some(id.into()) }
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     let res = unsafe {
         let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed();
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs
index f2404a62abf..92803c94c6e 100644
--- a/library/std/src/sys/pal/xous/thread.rs
+++ b/library/std/src/sys/pal/xous/thread.rs
@@ -145,6 +145,10 @@ impl Thread {
     }
 }
 
+pub(crate) fn current_os_id() -> Option<u64> {
+    None
+}
+
 pub fn available_parallelism() -> io::Result<NonZero<usize>> {
     // We're unicore right now.
     Ok(unsafe { NonZero::new_unchecked(1) })
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, R>(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
@@ -347,6 +347,13 @@ fn test_thread_id_not_equal() {
 }
 
 #[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);
     struct X<'scope, 'env>(&'scope Scope<'scope, 'env>, &'env AtomicBool);
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
index 9e6abf219f1..afabb8572bd 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/function_calls/exported_symbol_bad_unwind1.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/function_calls/exported_symbol_bad_unwind1.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
index 14b3be02a79..1246ad5a713 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.both.stderr
@@ -1,10 +1,10 @@
 
-thread 'main' panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
index 14b3be02a79..1246ad5a713 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.definition.stderr
@@ -1,10 +1,10 @@
 
-thread 'main' panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
index 5a3d5b4a5eb..e755b262474 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind2.extern_block.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/function_calls/exported_symbol_bad_unwind2.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
index 93720ca7d27..77dc2c61e26 100644
--- a/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
+++ b/src/tools/miri/tests/fail/function_calls/return_pointer_on_unwind.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/function_calls/return_pointer_on_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/function_calls/return_pointer_on_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/abort_unwind.stderr b/src/tools/miri/tests/fail/panic/abort_unwind.stderr
index 35052f37dfc..09f19a6e494 100644
--- a/src/tools/miri/tests/fail/panic/abort_unwind.stderr
+++ b/src/tools/miri/tests/fail/panic/abort_unwind.stderr
@@ -1,10 +1,10 @@
 
-thread 'main' panicked at tests/fail/panic/abort_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/abort_unwind.rs:LL:CC:
 PANIC!!!
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/src/tools/miri/tests/fail/panic/bad_unwind.stderr b/src/tools/miri/tests/fail/panic/bad_unwind.stderr
index b8404c4e457..b0a8492b6a6 100644
--- a/src/tools/miri/tests/fail/panic/bad_unwind.stderr
+++ b/src/tools/miri/tests/fail/panic/bad_unwind.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/panic/bad_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/bad_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/double_panic.stderr b/src/tools/miri/tests/fail/panic/double_panic.stderr
index 3f1fbfef721..f6aa0a34749 100644
--- a/src/tools/miri/tests/fail/panic/double_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/double_panic.stderr
@@ -1,14 +1,14 @@
 
-thread 'main' panicked at tests/fail/panic/double_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/double_panic.rs:LL:CC:
 first
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at tests/fail/panic/double_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/double_panic.rs:LL:CC:
 second
 stack backtrace:
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a destructor during cleanup
 thread caused non-unwinding panic. aborting.
 error: abnormal termination: the program aborted execution
diff --git a/src/tools/miri/tests/fail/panic/panic_abort1.stderr b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
index 9aca2ed654f..ebdf57f0f03 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort1.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort1.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/panic/panic_abort1.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/panic_abort1.rs:LL:CC:
 panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/panic_abort2.stderr b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
index 425817d5f86..d63e4ed79b2 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort2.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort2.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/panic/panic_abort2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/panic_abort2.rs:LL:CC:
 42-panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/panic_abort3.stderr b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
index a21e185219e..9751053396a 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort3.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort3.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/panic/panic_abort3.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/panic_abort3.rs:LL:CC:
 panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/panic_abort4.stderr b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
index a3cf5d72198..a84824fcc81 100644
--- a/src/tools/miri/tests/fail/panic/panic_abort4.stderr
+++ b/src/tools/miri/tests/fail/panic/panic_abort4.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/panic/panic_abort4.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/panic/panic_abort4.rs:LL:CC:
 42-panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr
index 1dcdb4a3996..ef87e7fe6db 100644
--- a/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/tls_macro_const_drop_panic.stderr
@@ -1,5 +1,5 @@
 
-thread $NAME panicked at tests/fail/panic/tls_macro_const_drop_panic.rs:LL:CC:
+thread $NAME ($TID) panicked at tests/fail/panic/tls_macro_const_drop_panic.rs:LL:CC:
 ow
 fatal runtime error: thread local panicked on drop, aborting
 error: abnormal termination: the program aborted execution
diff --git a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr
index 7e4907abd93..4fdaa97e1d0 100644
--- a/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/tls_macro_drop_panic.stderr
@@ -1,5 +1,5 @@
 
-thread $NAME panicked at tests/fail/panic/tls_macro_drop_panic.rs:LL:CC:
+thread $NAME ($TID) panicked at tests/fail/panic/tls_macro_drop_panic.rs:LL:CC:
 ow
 fatal runtime error: thread local panicked on drop, aborting
 error: abnormal termination: the program aborted execution
diff --git a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
index 8295a581060..d2b557f13f3 100644
--- a/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
+++ b/src/tools/miri/tests/fail/ptr_swap_nonoverlapping.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/fail/ptr_swap_nonoverlapping.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/ptr_swap_nonoverlapping.rs:LL:CC:
 unsafe precondition(s) violated: ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null and the specified memory ranges do not overlap
 
 This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr
index f0f305d76bc..96df302c397 100644
--- a/src/tools/miri/tests/fail/terminate-terminator.stderr
+++ b/src/tools/miri/tests/fail/terminate-terminator.stderr
@@ -1,12 +1,12 @@
 warning: You have explicitly enabled MIR optimizations, overriding Miri's default which is to completely disable them. Any optimizations may hide UB that Miri would otherwise detect, and it is not necessarily possible to predict what kind of UB will be missed. If you are enabling optimizations to make Miri run faster, we advise using cfg(miri) to shrink your workload instead. The performance benefit of enabling MIR optimizations is usually marginal at best.
 
 
-thread 'main' panicked at tests/fail/terminate-terminator.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/terminate-terminator.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/src/tools/miri/tests/fail/unwind-action-terminate.stderr b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
index 216ae84512a..06c63c70ede 100644
--- a/src/tools/miri/tests/fail/unwind-action-terminate.stderr
+++ b/src/tools/miri/tests/fail/unwind-action-terminate.stderr
@@ -1,10 +1,10 @@
 
-thread 'main' panicked at tests/fail/unwind-action-terminate.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/fail/unwind-action-terminate.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/panicking.rs:LL:CC:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr b/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
index 2be06968321..ad2bfc3f2a3 100644
--- a/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
+++ b/src/tools/miri/tests/panic/alloc_error_handler_hook.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/alloc_error_handler_hook.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/alloc_error_handler_hook.rs:LL:CC:
 alloc error hook called
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
index ddee4fd6ce3..7c2d089f952 100644
--- a/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
+++ b/src/tools/miri/tests/panic/alloc_error_handler_panic.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at RUSTLIB/std/src/alloc.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/std/src/alloc.rs:LL:CC:
 memory allocation of 4 bytes failed
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/div-by-zero-2.stderr b/src/tools/miri/tests/panic/div-by-zero-2.stderr
index 4d4b0062d5e..013f3cd3c20 100644
--- a/src/tools/miri/tests/panic/div-by-zero-2.stderr
+++ b/src/tools/miri/tests/panic/div-by-zero-2.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/div-by-zero-2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/div-by-zero-2.rs:LL:CC:
 attempt to divide by zero
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
index 8bcd635e8be..dad94377d12 100644
--- a/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
+++ b/src/tools/miri/tests/panic/function_calls/exported_symbol_good_unwind.stderr
@@ -1,11 +1,11 @@
 
-thread 'main' panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
 explicit panic
 
-thread 'main' panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/function_calls/exported_symbol_good_unwind.rs:LL:CC:
 explicit panic
diff --git a/src/tools/miri/tests/panic/mir-validation.rs b/src/tools/miri/tests/panic/mir-validation.rs
index e4b75cccbb5..b9097f2e8c5 100644
--- a/src/tools/miri/tests/panic/mir-validation.rs
+++ b/src/tools/miri/tests/panic/mir-validation.rs
@@ -8,6 +8,12 @@
 // Somehow on rustc Windows CI, the "Miri caused an ICE" message is not shown
 // and we don't even get a regular panic; rustc aborts with a different exit code instead.
 //@ignore-host: windows
+
+// FIXME: this tests a crash in rustc. For stage1, rustc is built with the downloaded standard
+// library which doesn't yet print the thread ID. Normalization can be removed at the stage bump.
+// For the grep: cfg(bootstrap)
+//@normalize-stderr-test: "thread 'rustc' panicked" -> "thread 'rustc' ($$TID) panicked"
+
 #![feature(custom_mir, core_intrinsics)]
 use core::intrinsics::mir::*;
 
diff --git a/src/tools/miri/tests/panic/mir-validation.stderr b/src/tools/miri/tests/panic/mir-validation.stderr
index f801ac907e6..1d40c93d709 100644
--- a/src/tools/miri/tests/panic/mir-validation.stderr
+++ b/src/tools/miri/tests/panic/mir-validation.stderr
@@ -6,7 +6,7 @@ LL |             *(tuple.0) = 1;
    |             ^^^^^^^^^^^^^^
 
 
-thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
+thread 'rustc' ($TID) panicked at compiler/rustc_mir_transform/src/validate.rs:LL:CC:
 Box<dyn Any>
 stack backtrace:
 
diff --git a/src/tools/miri/tests/panic/oob_subslice.stderr b/src/tools/miri/tests/panic/oob_subslice.stderr
index c0dabaff772..f8270f4ad4d 100644
--- a/src/tools/miri/tests/panic/oob_subslice.stderr
+++ b/src/tools/miri/tests/panic/oob_subslice.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/oob_subslice.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/oob_subslice.rs:LL:CC:
 range end index 5 out of range for slice of length 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
index d674e2beb8d..8e618b978ef 100644
--- a/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
+++ b/src/tools/miri/tests/panic/overflowing-lsh-neg.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/overflowing-lsh-neg.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/overflowing-lsh-neg.rs:LL:CC:
 attempt to shift left with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
index bb94f2e12c4..471bc849abb 100644
--- a/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
+++ b/src/tools/miri/tests/panic/overflowing-rsh-1.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/overflowing-rsh-1.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/overflowing-rsh-1.rs:LL:CC:
 attempt to shift right with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
index 0a29a57f3e1..94f5fb0f1ca 100644
--- a/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
+++ b/src/tools/miri/tests/panic/overflowing-rsh-2.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/overflowing-rsh-2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/overflowing-rsh-2.rs:LL:CC:
 attempt to shift right with overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic1.stderr b/src/tools/miri/tests/panic/panic1.stderr
index 130bc7737a4..9ca5234dd03 100644
--- a/src/tools/miri/tests/panic/panic1.stderr
+++ b/src/tools/miri/tests/panic/panic1.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/panic1.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/panic1.rs:LL:CC:
 panicking from libstd
 stack backtrace:
    0: std::panicking::begin_panic_handler
diff --git a/src/tools/miri/tests/panic/panic2.stderr b/src/tools/miri/tests/panic/panic2.stderr
index 157ffdb6b5d..c2e55178333 100644
--- a/src/tools/miri/tests/panic/panic2.stderr
+++ b/src/tools/miri/tests/panic/panic2.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/panic2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/panic2.rs:LL:CC:
 42-panicking from libstd
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic3.stderr b/src/tools/miri/tests/panic/panic3.stderr
index 529ef70870b..2fc761a4f3d 100644
--- a/src/tools/miri/tests/panic/panic3.stderr
+++ b/src/tools/miri/tests/panic/panic3.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/panic3.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/panic3.rs:LL:CC:
 panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/panic4.stderr b/src/tools/miri/tests/panic/panic4.stderr
index ecd07dd7ded..f2f4c038000 100644
--- a/src/tools/miri/tests/panic/panic4.stderr
+++ b/src/tools/miri/tests/panic/panic4.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/panic4.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/panic4.rs:LL:CC:
 42-panicking from libcore
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/panic/transmute_fat2.stderr b/src/tools/miri/tests/panic/transmute_fat2.stderr
index 71e2d7a8208..8846c4c7fbc 100644
--- a/src/tools/miri/tests/panic/transmute_fat2.stderr
+++ b/src/tools/miri/tests/panic/transmute_fat2.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at tests/panic/transmute_fat2.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/panic/transmute_fat2.rs:LL:CC:
 index out of bounds: the len is 0 but the index is 0
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
diff --git a/src/tools/miri/tests/pass/panic/catch_panic.stderr b/src/tools/miri/tests/pass/panic/catch_panic.stderr
index bc745fca578..cd7384fb107 100644
--- a/src/tools/miri/tests/pass/panic/catch_panic.stderr
+++ b/src/tools/miri/tests/pass/panic/catch_panic.stderr
@@ -1,47 +1,47 @@
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Hello from std::panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 Caught panic message (&str): Hello from std::panic
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Hello from std::panic: 1
 Caught panic message (String): Hello from std::panic: 1
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Hello from std::panic_any: 2
 Caught panic message (String): Hello from std::panic_any: 2
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Box<dyn Any>
 Failed to get caught panic message.
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Hello from core::panic
 Caught panic message (&str): Hello from core::panic
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 Hello from core::panic: 5
 Caught panic message (String): Hello from core::panic: 5
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 index out of bounds: the len is 3 but the index is 4
 Caught panic message (String): index out of bounds: the len is 3 but the index is 4
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 attempt to divide by zero
 Caught panic message (&str): attempt to divide by zero
 
-thread 'main' panicked at RUSTLIB/core/src/ptr/const_ptr.rs:LL:CC:
+thread 'main' ($TID) panicked at RUSTLIB/core/src/ptr/const_ptr.rs:LL:CC:
 align_offset: align is not a power-of-two
 Caught panic message (&str): align_offset: align is not a power-of-two
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 assertion failed: false
 Caught panic message (&str): assertion failed: false
 
-thread 'main' panicked at tests/pass/panic/catch_panic.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/catch_panic.rs:LL:CC:
 assertion failed: false
 Caught panic message (&str): assertion failed: false
 Success!
diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
index 4a3ac16debc..b388a3bedc0 100644
--- a/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
+++ b/src/tools/miri/tests/pass/panic/concurrent-panic.stderr
@@ -1,7 +1,7 @@
 Thread 1 starting, will block on mutex
 Thread 1 reported it has started
 
-thread '<unnamed>' panicked at tests/pass/panic/concurrent-panic.rs:LL:CC:
+thread '<unnamed>' ($TID) panicked at tests/pass/panic/concurrent-panic.rs:LL:CC:
 panic in thread 2
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
@@ -9,7 +9,7 @@ Thread 2 blocking on thread 1
 Thread 2 reported it has started
 Unlocking mutex
 
-thread '<unnamed>' panicked at tests/pass/panic/concurrent-panic.rs:LL:CC:
+thread '<unnamed>' ($TID) panicked at tests/pass/panic/concurrent-panic.rs:LL:CC:
 panic in thread 1
 Thread 1 has exited
 Thread 2 has exited
diff --git a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
index 8aff8f6ec55..7ae39204d4e 100644
--- a/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
+++ b/src/tools/miri/tests/pass/panic/nested_panic_caught.stderr
@@ -1,9 +1,9 @@
 
-thread 'main' panicked at tests/pass/panic/nested_panic_caught.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/nested_panic_caught.rs:LL:CC:
 once
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'main' panicked at tests/pass/panic/nested_panic_caught.rs:LL:CC:
+thread 'main' ($TID) panicked at tests/pass/panic/nested_panic_caught.rs:LL:CC:
 twice
 stack backtrace:
diff --git a/src/tools/miri/tests/pass/panic/thread_panic.stderr b/src/tools/miri/tests/pass/panic/thread_panic.stderr
index 3bb2991805c..92403d5152d 100644
--- a/src/tools/miri/tests/pass/panic/thread_panic.stderr
+++ b/src/tools/miri/tests/pass/panic/thread_panic.stderr
@@ -1,8 +1,8 @@
 
-thread '<unnamed>' panicked at tests/pass/panic/thread_panic.rs:LL:CC:
+thread '<unnamed>' ($TID) panicked at tests/pass/panic/thread_panic.rs:LL:CC:
 Hello!
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect
 
-thread 'childthread' panicked at tests/pass/panic/thread_panic.rs:LL:CC:
+thread 'childthread' ($TID) panicked at tests/pass/panic/thread_panic.rs:LL:CC:
 Hello, world!
diff --git a/src/tools/rustfmt/tests/rustfmt/main.rs b/src/tools/rustfmt/tests/rustfmt/main.rs
index a9f58b9328e..4a9399377d1 100644
--- a/src/tools/rustfmt/tests/rustfmt/main.rs
+++ b/src/tools/rustfmt/tests/rustfmt/main.rs
@@ -185,10 +185,11 @@ fn dont_emit_ICE() {
         "tests/target/issue-6105.rs",
     ];
 
+    let panic_re = regex::Regex::new("thread.*panicked").unwrap();
     for file in files {
         let args = [file];
         let (_stdout, stderr) = rustfmt(&args);
-        assert!(!stderr.contains("thread 'main' panicked"));
+        assert!(!panic_re.is_match(&stderr));
     }
 }
 
diff --git a/tests/run-make/libtest-json/output-default.json b/tests/run-make/libtest-json/output-default.json
index a6a8a9f3b47..5371715d17c 100644
--- a/tests/run-make/libtest-json/output-default.json
+++ b/tests/run-make/libtest-json/output-default.json
@@ -2,7 +2,7 @@
 { "type": "test", "event": "started", "name": "a" }
 { "type": "test", "name": "a", "event": "ok" }
 { "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "\nthread 'b' panicked at f.rs:9:5:\nassertion failed: false\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "\nthread 'b' ($TID) panicked at f.rs:9:5:\nassertion failed: false\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
 { "type": "test", "event": "started", "name": "c" }
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
diff --git a/tests/run-make/libtest-json/output-stdout-success.json b/tests/run-make/libtest-json/output-stdout-success.json
index a6c36e746b3..5caadcf56cf 100644
--- a/tests/run-make/libtest-json/output-stdout-success.json
+++ b/tests/run-make/libtest-json/output-stdout-success.json
@@ -2,9 +2,9 @@
 { "type": "test", "event": "started", "name": "a" }
 { "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
 { "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "\nthread 'b' panicked at f.rs:9:5:\nassertion failed: false\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "\nthread 'b' ($TID) panicked at f.rs:9:5:\nassertion failed: false\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" }
 { "type": "test", "event": "started", "name": "c" }
-{ "type": "test", "name": "c", "event": "ok", "stdout": "\nthread 'c' panicked at f.rs:15:5:\nassertion failed: false\n" }
+{ "type": "test", "name": "c", "event": "ok", "stdout": "\nthread 'c' ($TID) panicked at f.rs:15:5:\nassertion failed: false\n" }
 { "type": "test", "event": "started", "name": "d" }
 { "type": "test", "name": "d", "event": "ignored", "message": "msg" }
 { "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": "$EXEC_TIME" }
diff --git a/tests/run-make/libtest-json/rmake.rs b/tests/run-make/libtest-json/rmake.rs
index c31f4a79b64..034ba6246f1 100644
--- a/tests/run-make/libtest-json/rmake.rs
+++ b/tests/run-make/libtest-json/rmake.rs
@@ -38,5 +38,6 @@ fn run_tests(extra_args: &[&str], expected_file: &str) {
         .expected_file(expected_file)
         .actual_text("stdout", test_stdout)
         .normalize(r#"(?<prefix>"exec_time": )[0-9.]+"#, r#"${prefix}"$$EXEC_TIME""#)
+        .normalize(r"thread '(?P<name>.*?)' \(\d+\) panicked", "thread '$name' ($$TID) panicked")
         .run();
 }
diff --git a/tests/run-make/libtest-junit/output-default.xml b/tests/run-make/libtest-junit/output-default.xml
index aa1b8c855aa..2467d8d940a 100644
--- a/tests/run-make/libtest-junit/output-default.xml
+++ b/tests/run-make/libtest-junit/output-default.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"/><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;&#xA;<![CDATA[thread 'b' panicked at f.rs:10:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
+<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"/><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;&#xA;<![CDATA[thread 'b' ($TID) panicked at f.rs:10:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"/><system-out/><system-err/></testsuite></testsuites>
diff --git a/tests/run-make/libtest-junit/output-stdout-success.xml b/tests/run-make/libtest-junit/output-stdout-success.xml
index 2592ec7efb1..6bf1d7008a4 100644
--- a/tests/run-make/libtest-junit/output-stdout-success.xml
+++ b/tests/run-make/libtest-junit/output-stdout-success.xml
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"><system-out><![CDATA[print from successful test]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;&#xA;<![CDATA[thread 'b' panicked at f.rs:10:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"><system-out><![CDATA[]]>&#xA;<![CDATA[thread 'c' panicked at f.rs:16:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[]]></system-out></testcase><system-out/><system-err/></testsuite></testsuites>
+<?xml version="1.0" encoding="UTF-8"?><testsuites><testsuite name="test" package="test" id="0" errors="0" failures="1" tests="4" skipped="1" ><testcase classname="unknown" name="a" time="$TIME"><system-out><![CDATA[print from successful test]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="b" time="$TIME"><failure type="assert"/><system-out><![CDATA[print from failing test]]>&#xA;&#xA;<![CDATA[thread 'b' ($TID) panicked at f.rs:10:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace]]>&#xA;<![CDATA[]]></system-out></testcase><testcase classname="unknown" name="c" time="$TIME"><system-out><![CDATA[]]>&#xA;<![CDATA[thread 'c' ($TID) panicked at f.rs:16:5:]]>&#xA;<![CDATA[assertion failed: false]]>&#xA;<![CDATA[]]></system-out></testcase><system-out/><system-err/></testsuite></testsuites>
diff --git a/tests/run-make/libtest-junit/rmake.rs b/tests/run-make/libtest-junit/rmake.rs
index 5917660b6c7..6961be21513 100644
--- a/tests/run-make/libtest-junit/rmake.rs
+++ b/tests/run-make/libtest-junit/rmake.rs
@@ -27,5 +27,6 @@ fn run_tests(extra_args: &[&str], expected_file: &str) {
         .expected_file(expected_file)
         .actual_text("stdout", test_stdout)
         .normalize(r#"\btime="[0-9.]+""#, r#"time="$$TIME""#)
+        .normalize(r"thread '(?P<name>.*?)' \(\d+\) panicked", "thread '$name' ($$TID) panicked")
         .run();
 }
diff --git a/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
index ab6aca239af..c8acbe4eda7 100644
--- a/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
+++ b/tests/rustdoc-ui/doctest/edition-2024-error-output.stdout
@@ -9,7 +9,7 @@ Test executable failed (exit status: 101).
 
 stderr:
 
-thread 'main' panicked at $TMP:6:1:
+thread 'main' ($TID) panicked at $TMP:6:1:
 assertion `left == right` failed
   left: 4
  right: 5
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout
index 7aa965d543b..12a59d435fe 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout
+++ b/tests/rustdoc-ui/doctest/failed-doctest-output-windows.stdout
@@ -27,7 +27,7 @@ stderr:
 stderr 1
 stderr 2
 
-thread 'main' panicked at $DIR/failed-doctest-output-windows.rs:7:1:
+thread 'main' ($TID) panicked at $DIR/failed-doctest-output-windows.rs:7:1:
 oh no
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
diff --git a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout
index a333f341ce5..3dbb2179b8f 100644
--- a/tests/rustdoc-ui/doctest/failed-doctest-output.stdout
+++ b/tests/rustdoc-ui/doctest/failed-doctest-output.stdout
@@ -27,7 +27,7 @@ stderr:
 stderr 1
 stderr 2
 
-thread 'main' panicked at $DIR/failed-doctest-output.rs:7:1:
+thread 'main' ($TID) panicked at $DIR/failed-doctest-output.rs:7:1:
 oh no
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
diff --git a/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout b/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout
index a35a4d7c3cb..dfdcd7759d5 100644
--- a/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout
+++ b/tests/rustdoc-ui/doctest/stdout-and-stderr.stdout
@@ -14,7 +14,7 @@ stdout:
 
 stderr:
 
-thread 'main' panicked at $TMP:7:1:
+thread 'main' ($TID) panicked at $TMP:7:1:
 assertion `left == right` failed
   left: "doc"
  right: "test"
@@ -26,7 +26,7 @@ Test executable failed (exit status: 101).
 
 stderr:
 
-thread 'main' panicked at $TMP:15:1:
+thread 'main' ($TID) panicked at $TMP:15:1:
 assertion `left == right` failed
   left: "doc"
  right: "test"
diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout
index 87d1e772b80..08f7a4ddd3a 100644
--- a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout
+++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout
@@ -9,7 +9,7 @@ Test executable failed (exit status: 101).
 
 stderr:
 
-thread 'main' panicked at remapped_path/remap-path-prefix-failed-doctest-output.rs:3:1:
+thread 'main' ($TID) panicked at remapped_path/remap-path-prefix-failed-doctest-output.rs:3:1:
 oh no
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs
index a8b05a4befa..ed99614914a 100644
--- a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs
+++ b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-completion.rs
@@ -2,7 +2,7 @@
 // be talking about `async fn`s instead.
 
 //@ run-fail
-//@ error-pattern: thread 'main' panicked
+//@ regex-error-pattern: thread 'main'.*panicked
 //@ error-pattern: `async fn` resumed after completion
 //@ edition:2018
 
diff --git a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
index 94366e66263..881fafb010f 100644
--- a/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
+++ b/tests/ui/async-await/issues/issue-65419/issue-65419-async-fn-resume-after-panic.rs
@@ -3,7 +3,7 @@
 
 //@ run-fail
 //@ needs-unwind
-//@ error-pattern: thread 'main' panicked
+//@ regex-error-pattern: thread 'main'.*panicked
 //@ error-pattern: `async fn` resumed after panicking
 //@ edition:2018
 
diff --git a/tests/ui/backtrace/synchronized-panic-handler.run.stderr b/tests/ui/backtrace/synchronized-panic-handler.run.stderr
index 7a60ef2da60..c604d49c193 100644
--- a/tests/ui/backtrace/synchronized-panic-handler.run.stderr
+++ b/tests/ui/backtrace/synchronized-panic-handler.run.stderr
@@ -1,7 +1,7 @@
 
-thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:11:5:
+thread '<unnamed>' ($TID) panicked at $DIR/synchronized-panic-handler.rs:11:5:
 oops oh no woe is me
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread '<unnamed>' panicked at $DIR/synchronized-panic-handler.rs:11:5:
+thread '<unnamed>' ($TID) panicked at $DIR/synchronized-panic-handler.rs:11:5:
 oops oh no woe is me
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
index 73357d208c0..ac4d9fc0f4f 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-80742.rs
@@ -2,7 +2,7 @@
 //@ known-bug: #97477
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
 //@ rustc-env:RUST_BACKTRACE=0
 
diff --git a/tests/ui/extern/extern-types-field-offset.run.stderr b/tests/ui/extern/extern-types-field-offset.run.stderr
index 07bd4fcb13f..b096e8044a7 100644
--- a/tests/ui/extern/extern-types-field-offset.run.stderr
+++ b/tests/ui/extern/extern-types-field-offset.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+thread 'main' ($TID) panicked at library/core/src/panicking.rs:$LINE:$COL:
 attempted to compute the size or alignment of extern type `Opaque`
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/extern/extern-types-size_of_val.align.run.stderr b/tests/ui/extern/extern-types-size_of_val.align.run.stderr
index 5ba372d60fa..66206f37501 100644
--- a/tests/ui/extern/extern-types-size_of_val.align.run.stderr
+++ b/tests/ui/extern/extern-types-size_of_val.align.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+thread 'main' ($TID) panicked at library/core/src/panicking.rs:$LINE:$COL:
 attempted to compute the size or alignment of extern type `A`
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/extern/extern-types-size_of_val.size.run.stderr b/tests/ui/extern/extern-types-size_of_val.size.run.stderr
index 5ba372d60fa..66206f37501 100644
--- a/tests/ui/extern/extern-types-size_of_val.size.run.stderr
+++ b/tests/ui/extern/extern-types-size_of_val.size.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+thread 'main' ($TID) panicked at library/core/src/panicking.rs:$LINE:$COL:
 attempted to compute the size or alignment of extern type `A`
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr
index 5cd07dcda4c..d28ab864183 100644
--- a/tests/ui/hygiene/panic-location.run.stderr
+++ b/tests/ui/hygiene/panic-location.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at $DIR/panic-location.rs:LL:CC:
+thread 'main' ($TID) panicked at $DIR/panic-location.rs:LL:CC:
 capacity overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
index 71d792b7f77..397eeaf600a 100644
--- a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
+++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
+thread 'main' ($TID) panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
 byte index 1 is out of bounds of ``
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr
index 4f11f5966ed..649174017e9 100644
--- a/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr
+++ b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at $DIR/const-eval-select-backtrace.rs:15:5:
+thread 'main' ($TID) panicked at $DIR/const-eval-select-backtrace.rs:15:5:
 Aaah!
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs
index 2359eee8b26..ce855483527 100644
--- a/tests/ui/intrinsics/not-overridden.rs
+++ b/tests/ui/intrinsics/not-overridden.rs
@@ -4,7 +4,7 @@
 //@ build-fail
 //@ failure-status:101
 //@ normalize-stderr: ".*note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*:\n.*\n" -> ""
 //@ normalize-stderr: "internal compiler error:.*: intrinsic const_deallocate " -> ""
 //@ rustc-env:RUST_BACKTRACE=0
 
diff --git a/tests/ui/issues/issue-87707.run.stderr b/tests/ui/issues/issue-87707.run.stderr
index eb1d65a081f..8485c0578b8 100644
--- a/tests/ui/issues/issue-87707.run.stderr
+++ b/tests/ui/issues/issue-87707.run.stderr
@@ -1,7 +1,7 @@
 
-thread 'main' panicked at $DIR/issue-87707.rs:14:24:
+thread 'main' ($TID) panicked at $DIR/issue-87707.rs:14:24:
 Here Once instance is poisoned.
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'main' panicked at $DIR/issue-87707.rs:16:7:
+thread 'main' ($TID) panicked at $DIR/issue-87707.rs:16:7:
 Once instance has previously been poisoned
diff --git a/tests/ui/layout/valid_range_oob.rs b/tests/ui/layout/valid_range_oob.rs
index df816e74066..8ae9f6e9726 100644
--- a/tests/ui/layout/valid_range_oob.rs
+++ b/tests/ui/layout/valid_range_oob.rs
@@ -1,6 +1,6 @@
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ rustc-env:RUST_BACKTRACE=0
 
 #![feature(rustc_attrs)]
diff --git a/tests/ui/macros/assert-long-condition.run.stderr b/tests/ui/macros/assert-long-condition.run.stderr
index c2c5fe5d7d5..a9fac037143 100644
--- a/tests/ui/macros/assert-long-condition.run.stderr
+++ b/tests/ui/macros/assert-long-condition.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/assert-long-condition.rs:7:5:
+thread 'main' ($TID) panicked at $DIR/assert-long-condition.rs:7:5:
 assertion failed: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18
                                 + 19 + 20 + 21 + 22 + 23 + 24 + 25 == 0
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/mir/lint/storage-live.rs b/tests/ui/mir/lint/storage-live.rs
index 252e3b8456c..32bd32754dd 100644
--- a/tests/ui/mir/lint/storage-live.rs
+++ b/tests/ui/mir/lint/storage-live.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Zlint-mir -Ztreat-err-as-bug
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ normalize-stderr: "storage_live\[....\]" -> "storage_live[HASH]"
 //@ normalize-stderr: "(delayed at [^:]+):\d+:\d+ - " -> "$1:LL:CC - "
 //@ rustc-env:RUST_BACKTRACE=0
diff --git a/tests/ui/nll/issue-51345-2.rs b/tests/ui/nll/issue-51345-2.rs
index 39871d56a9a..6c424d436f1 100644
--- a/tests/ui/nll/issue-51345-2.rs
+++ b/tests/ui/nll/issue-51345-2.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:explicit panic
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: explicit panic
 //@ needs-subprocess
 
 fn main() {
diff --git a/tests/ui/numbers-arithmetic/overflowing-add.rs b/tests/ui/numbers-arithmetic/overflowing-add.rs
index c1f498c802b..a63fc3bccf1 100644
--- a/tests/ui/numbers-arithmetic/overflowing-add.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-add.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:attempt to add with overflow
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: attempt to add with overflow
 //@ compile-flags: -C debug-assertions
 //@ needs-subprocess
 
diff --git a/tests/ui/numbers-arithmetic/overflowing-mul.rs b/tests/ui/numbers-arithmetic/overflowing-mul.rs
index 0eece536929..2645a32d5ad 100644
--- a/tests/ui/numbers-arithmetic/overflowing-mul.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-mul.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:attempt to multiply with overflow
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: attempt to multiply with overflow
 //@ needs-subprocess
 //@ compile-flags: -C debug-assertions
 
diff --git a/tests/ui/numbers-arithmetic/overflowing-pow-signed.rs b/tests/ui/numbers-arithmetic/overflowing-pow-signed.rs
index 28deb7cf6ba..6db6682e16f 100644
--- a/tests/ui/numbers-arithmetic/overflowing-pow-signed.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-pow-signed.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:attempt to multiply with overflow
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: attempt to multiply with overflow
 //@ needs-subprocess
 //@ compile-flags: -C debug-assertions
 
diff --git a/tests/ui/numbers-arithmetic/overflowing-pow-unsigned.rs b/tests/ui/numbers-arithmetic/overflowing-pow-unsigned.rs
index dea9a4d5428..bde0de6f6f5 100644
--- a/tests/ui/numbers-arithmetic/overflowing-pow-unsigned.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-pow-unsigned.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:attempt to multiply with overflow
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: attempt to multiply with overflow
 //@ needs-subprocess
 //@ compile-flags: -C debug-assertions
 
diff --git a/tests/ui/numbers-arithmetic/overflowing-sub.rs b/tests/ui/numbers-arithmetic/overflowing-sub.rs
index 88b1b693f63..1718fccad7a 100644
--- a/tests/ui/numbers-arithmetic/overflowing-sub.rs
+++ b/tests/ui/numbers-arithmetic/overflowing-sub.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:attempt to subtract with overflow
+//@ regex-error-pattern: thread 'main'.*panicked
+//@ error-pattern: attempt to subtract with overflow
 //@ needs-subprocess
 //@ compile-flags: -C debug-assertions
 
diff --git a/tests/ui/panics/fmt-only-once.run.stderr b/tests/ui/panics/fmt-only-once.run.stderr
index faa3cc91151..f0124e4cb77 100644
--- a/tests/ui/panics/fmt-only-once.run.stderr
+++ b/tests/ui/panics/fmt-only-once.run.stderr
@@ -1,5 +1,5 @@
 fmt
 
-thread 'main' panicked at $DIR/fmt-only-once.rs:20:5:
+thread 'main' ($TID) panicked at $DIR/fmt-only-once.rs:20:5:
 PrintOnFmt
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/issue-47429-short-backtraces.run.stderr b/tests/ui/panics/issue-47429-short-backtraces.run.stderr
index 32dc6592271..13b59a7c7af 100644
--- a/tests/ui/panics/issue-47429-short-backtraces.run.stderr
+++ b/tests/ui/panics/issue-47429-short-backtraces.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/issue-47429-short-backtraces.rs:24:5:
+thread 'main' ($TID) panicked at $DIR/issue-47429-short-backtraces.rs:24:5:
 explicit panic
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/location-detail-panic-no-column.run.stderr b/tests/ui/panics/location-detail-panic-no-column.run.stderr
index f63c09652b8..8f43936a0af 100644
--- a/tests/ui/panics/location-detail-panic-no-column.run.stderr
+++ b/tests/ui/panics/location-detail-panic-no-column.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at $DIR/location-detail-panic-no-column.rs:7:0:
+thread 'main' ($TID) panicked at $DIR/location-detail-panic-no-column.rs:7:0:
 column-redacted
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/location-detail-panic-no-file.run.stderr b/tests/ui/panics/location-detail-panic-no-file.run.stderr
index 3d1c6defa31..8d0ee148006 100644
--- a/tests/ui/panics/location-detail-panic-no-file.run.stderr
+++ b/tests/ui/panics/location-detail-panic-no-file.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at <redacted>:7:5:
+thread 'main' ($TID) panicked at <redacted>:7:5:
 file-redacted
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/location-detail-panic-no-line.run.stderr b/tests/ui/panics/location-detail-panic-no-line.run.stderr
index 9809ab5e2b4..79f5c012b8a 100644
--- a/tests/ui/panics/location-detail-panic-no-line.run.stderr
+++ b/tests/ui/panics/location-detail-panic-no-line.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at $DIR/location-detail-panic-no-line.rs:0:5:
+thread 'main' ($TID) panicked at $DIR/location-detail-panic-no-line.rs:0:5:
 line-redacted
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/location-detail-panic-no-location-info.run.stderr b/tests/ui/panics/location-detail-panic-no-location-info.run.stderr
index f68a0d663c0..12b3e1b53e3 100644
--- a/tests/ui/panics/location-detail-panic-no-location-info.run.stderr
+++ b/tests/ui/panics/location-detail-panic-no-location-info.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at <redacted>:0:0:
+thread 'main' ($TID) panicked at <redacted>:0:0:
 no location info
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/location-detail-unwrap-no-file.run.stderr b/tests/ui/panics/location-detail-unwrap-no-file.run.stderr
index af4a4997fae..a4a87423cdc 100644
--- a/tests/ui/panics/location-detail-unwrap-no-file.run.stderr
+++ b/tests/ui/panics/location-detail-unwrap-no-file.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at <redacted>:8:9:
+thread 'main' ($TID) panicked at <redacted>:8:9:
 called `Option::unwrap()` on a `None` value
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/panics/main-panic.rs b/tests/ui/panics/main-panic.rs
index 0b3d5c3aaec..9f2a92da90f 100644
--- a/tests/ui/panics/main-panic.rs
+++ b/tests/ui/panics/main-panic.rs
@@ -1,5 +1,5 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked at
+//@ regex-error-pattern: thread 'main' \(\d+\) panicked at
 //@ needs-subprocess
 
 fn main() {
diff --git a/tests/ui/panics/panic-in-cleanup.run.stderr b/tests/ui/panics/panic-in-cleanup.run.stderr
index 34383562c36..bfe3dc8c9d7 100644
--- a/tests/ui/panics/panic-in-cleanup.run.stderr
+++ b/tests/ui/panics/panic-in-cleanup.run.stderr
@@ -1,12 +1,12 @@
 
-thread 'main' panicked at $DIR/panic-in-cleanup.rs:22:5:
+thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:22:5:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'main' panicked at $DIR/panic-in-cleanup.rs:16:9:
+thread 'main' ($TID) panicked at $DIR/panic-in-cleanup.rs:16:9:
 BOOM
 stack backtrace:
 
-thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+thread 'main' ($TID) panicked at library/core/src/panicking.rs:$LINE:$COL:
 panic in a destructor during cleanup
 thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/panics/panic-in-ffi.run.stderr b/tests/ui/panics/panic-in-ffi.run.stderr
index a6f3ebe5657..ce907d64358 100644
--- a/tests/ui/panics/panic-in-ffi.run.stderr
+++ b/tests/ui/panics/panic-in-ffi.run.stderr
@@ -1,10 +1,10 @@
 
-thread 'main' panicked at $DIR/panic-in-ffi.rs:21:5:
+thread 'main' ($TID) panicked at $DIR/panic-in-ffi.rs:21:5:
 Test
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 Noisy Drop
 
-thread 'main' panicked at library/core/src/panicking.rs:$LINE:$COL:
+thread 'main' ($TID) panicked at library/core/src/panicking.rs:$LINE:$COL:
 panic in a function that cannot unwind
 stack backtrace:
 thread caused non-unwinding panic. aborting.
diff --git a/tests/ui/panics/panic-set-unset-handler.rs b/tests/ui/panics/panic-set-unset-handler.rs
index 66d5003d0f1..4f646020037 100644
--- a/tests/ui/panics/panic-set-unset-handler.rs
+++ b/tests/ui/panics/panic-set-unset-handler.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:foobar
+//@ regex-error-pattern: thread 'main' \(\d+\) panicked
+//@ error-pattern: foobar
 //@ needs-subprocess
 
 use std::panic;
diff --git a/tests/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr b/tests/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr
index 799a8b30e99..c3c1ce16a4b 100644
--- a/tests/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr
+++ b/tests/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5
+thread 'main' ($TID) panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5
 stack backtrace:
    0: std::panicking::begin_panic
    1: d
diff --git a/tests/ui/panics/panic-take-handler-nop.rs b/tests/ui/panics/panic-take-handler-nop.rs
index f10582872df..ebea3ef0685 100644
--- a/tests/ui/panics/panic-take-handler-nop.rs
+++ b/tests/ui/panics/panic-take-handler-nop.rs
@@ -1,6 +1,6 @@
 //@ run-fail
-//@ error-pattern:thread 'main' panicked
-//@ error-pattern:foobar
+//@ regex-error-pattern: thread 'main' \(\d+\) panicked
+//@ error-pattern: foobar
 //@ needs-subprocess
 
 use std::panic;
diff --git a/tests/ui/panics/panic-task-name-none.rs b/tests/ui/panics/panic-task-name-none.rs
index 8695771ff5e..4471cd6795c 100644
--- a/tests/ui/panics/panic-task-name-none.rs
+++ b/tests/ui/panics/panic-task-name-none.rs
@@ -1,14 +1,14 @@
 //@ run-fail
-//@ error-pattern:thread '<unnamed>' panicked
-//@ error-pattern:test
+//@ regex-error-pattern: thread '<unnamed>' \(\d+\) panicked
+//@ error-pattern: test
 //@ needs-threads
 
 use std::thread;
 
 fn main() {
     let r: Result<(), _> = thread::spawn(move || {
-                               panic!("test");
-                           })
-                               .join();
+        panic!("test");
+    })
+    .join();
     assert!(r.is_ok());
 }
diff --git a/tests/ui/panics/panic-task-name-owned.rs b/tests/ui/panics/panic-task-name-owned.rs
index 42ae33b5d35..084ac90512a 100644
--- a/tests/ui/panics/panic-task-name-owned.rs
+++ b/tests/ui/panics/panic-task-name-owned.rs
@@ -1,19 +1,19 @@
 //@ run-fail
-//@ error-pattern:thread 'owned name' panicked
-//@ error-pattern:test
+//@ regex-error-pattern: thread 'owned name' \(\d+\) panicked
+//@ error-pattern: test
 //@ needs-threads
 
 use std::thread::Builder;
 
 fn main() {
     let r: () = Builder::new()
-                    .name("owned name".to_string())
-                    .spawn(move || {
-                        panic!("test");
-                        ()
-                    })
-                    .unwrap()
-                    .join()
-                    .unwrap();
+        .name("owned name".to_string())
+        .spawn(move || {
+            panic!("test");
+            ()
+        })
+        .unwrap()
+        .join()
+        .unwrap();
     panic!();
 }
diff --git a/tests/ui/panics/runtime-switch.run.stderr b/tests/ui/panics/runtime-switch.run.stderr
index 70ed127af86..f3f60445952 100644
--- a/tests/ui/panics/runtime-switch.run.stderr
+++ b/tests/ui/panics/runtime-switch.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/runtime-switch.rs:28:5:
+thread 'main' ($TID) panicked at $DIR/runtime-switch.rs:28:5:
 explicit panic
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
index 664d51e185d..584b477f3a7 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:62:5:
+thread 'main' ($TID) panicked at $DIR/short-ice-remove-middle-frames-2.rs:62:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
index e966462331f..1efcb7d5304 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
@@ -1,5 +1,5 @@
 
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:58:5:
+thread 'main' ($TID) panicked at $DIR/short-ice-remove-middle-frames.rs:58:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/proc-macro/load-panic-backtrace.rs b/tests/ui/proc-macro/load-panic-backtrace.rs
index 848bdaf9f37..82645eb4e9f 100644
--- a/tests/ui/proc-macro/load-panic-backtrace.rs
+++ b/tests/ui/proc-macro/load-panic-backtrace.rs
@@ -1,7 +1,7 @@
 //@ proc-macro: test-macros.rs
 //@ compile-flags: -Z proc-macro-backtrace
 //@ rustc-env:RUST_BACKTRACE=0
-//@ normalize-stderr: "thread '.*' panicked " -> ""
+//@ normalize-stderr: "thread '.*' \(0x[[:xdigit:]]+\) panicked " -> ""
 //@ normalize-stderr: "note:.*RUST_BACKTRACE=1.*\n" -> ""
 //@ needs-unwind proc macro panics to report errors
 
diff --git a/tests/ui/proc-macro/load-panic-backtrace.stderr b/tests/ui/proc-macro/load-panic-backtrace.stderr
index a1049f5a324..b8872eb12b7 100644
--- a/tests/ui/proc-macro/load-panic-backtrace.stderr
+++ b/tests/ui/proc-macro/load-panic-backtrace.stderr
@@ -1,5 +1,5 @@
 
-at $DIR/auxiliary/test-macros.rs:38:5:
+thread '<unnamed>' ($TID) panicked at $DIR/auxiliary/test-macros.rs:38:5:
 panic-derive
 error: proc-macro derive panicked
   --> $DIR/load-panic-backtrace.rs:11:10
diff --git a/tests/ui/process/multi-panic.rs b/tests/ui/process/multi-panic.rs
index 481fe75c731..1fddffeb770 100644
--- a/tests/ui/process/multi-panic.rs
+++ b/tests/ui/process/multi-panic.rs
@@ -7,18 +7,27 @@ fn check_for_no_backtrace(test: std::process::Output) {
     let err = String::from_utf8_lossy(&test.stderr);
     let mut it = err.lines().filter(|l| !l.is_empty());
 
-    assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked")), Some(true));
-    assert_eq!(it.next().is_some(), true);
+    assert_eq!(
+        it.next().map(|l| l.starts_with("thread '<unnamed>' (") && l.contains("panicked")),
+        Some(true),
+        "out: ```{err}```",
+    );
+    assert_eq!(it.next().is_some(), true, "out: ```{err}```");
     assert_eq!(
         it.next(),
         Some(
             "note: run with `RUST_BACKTRACE=1` \
                                 environment variable to display a backtrace"
-        )
+        ),
+        "out: ```{err}```",
+    );
+    assert_eq!(
+        it.next().map(|l| l.starts_with("thread 'main' (") && l.contains("panicked at")),
+        Some(true),
+        "out: ```{err}```",
     );
-    assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true));
-    assert_eq!(it.next().is_some(), true);
-    assert_eq!(it.next(), None);
+    assert_eq!(it.next().is_some(), true, "out: ```{err}```");
+    assert_eq!(it.next(), None, "out: ```{err}```");
 }
 
 fn main() {
diff --git a/tests/ui/process/println-with-broken-pipe.run.stderr b/tests/ui/process/println-with-broken-pipe.run.stderr
index ab414994b56..c56793de525 100644
--- a/tests/ui/process/println-with-broken-pipe.run.stderr
+++ b/tests/ui/process/println-with-broken-pipe.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'main' panicked at library/std/src/io/stdio.rs:LL:CC:
+thread 'main' ($TID) panicked at library/std/src/io/stdio.rs:LL:CC:
 failed printing to stdout: Broken pipe (os error 32)
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/resolve/multiple_definitions_attribute_merging.rs b/tests/ui/resolve/multiple_definitions_attribute_merging.rs
index 155abafdd9d..519b989fbe8 100644
--- a/tests/ui/resolve/multiple_definitions_attribute_merging.rs
+++ b/tests/ui/resolve/multiple_definitions_attribute_merging.rs
@@ -5,7 +5,7 @@
 //@known-bug: #120873
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
 //@ rustc-env:RUST_BACKTRACE=0
 
diff --git a/tests/ui/resolve/proc_macro_generated_packed.rs b/tests/ui/resolve/proc_macro_generated_packed.rs
index 0cba3c1616d..41236c732bb 100644
--- a/tests/ui/resolve/proc_macro_generated_packed.rs
+++ b/tests/ui/resolve/proc_macro_generated_packed.rs
@@ -5,7 +5,7 @@
 //@known-bug: #120873
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
 //@ rustc-env:RUST_BACKTRACE=0
 
diff --git a/tests/ui/test-attrs/terse.run.stdout b/tests/ui/test-attrs/terse.run.stdout
index ac1ac28c98d..381d3cbe675 100644
--- a/tests/ui/test-attrs/terse.run.stdout
+++ b/tests/ui/test-attrs/terse.run.stdout
@@ -10,18 +10,18 @@ failures:
 
 ---- abc stdout ----
 
-thread 'abc' panicked at $DIR/terse.rs:12:5:
+thread 'abc' ($TID) panicked at $DIR/terse.rs:12:5:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 ---- foo stdout ----
 
-thread 'foo' panicked at $DIR/terse.rs:17:5:
+thread 'foo' ($TID) panicked at $DIR/terse.rs:17:5:
 explicit panic
 
 ---- foo2 stdout ----
 
-thread 'foo2' panicked at $DIR/terse.rs:22:5:
+thread 'foo2' ($TID) panicked at $DIR/terse.rs:22:5:
 explicit panic
 
 
diff --git a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
index b9f267838b1..8d7c62f8ec7 100644
--- a/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-panic-abort-nocapture.run.stderr
@@ -1,11 +1,11 @@
 
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:32:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:32:5:
 assertion `left == right` failed
   left: 2
  right: 4
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'main' panicked at $DIR/test-panic-abort-nocapture.rs:26:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort-nocapture.rs:26:5:
 assertion `left == right` failed
   left: 2
  right: 4
diff --git a/tests/ui/test-attrs/test-panic-abort.run.stdout b/tests/ui/test-attrs/test-panic-abort.run.stdout
index 0faa7f0dfce..4d65c05b944 100644
--- a/tests/ui/test-attrs/test-panic-abort.run.stdout
+++ b/tests/ui/test-attrs/test-panic-abort.run.stdout
@@ -18,7 +18,7 @@ testing123
 ---- it_fails stderr ----
 testing321
 
-thread 'main' panicked at $DIR/test-panic-abort.rs:37:5:
+thread 'main' ($TID) panicked at $DIR/test-panic-abort.rs:37:5:
 assertion `left == right` failed
   left: 2
  right: 5
diff --git a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr
index db379a16b52..63bc10ef5ea 100644
--- a/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr
+++ b/tests/ui/test-attrs/test-should-panic-failed-show-span.run.stderr
@@ -1,13 +1,13 @@
 
-thread 'should_panic_with_any_message' panicked at $DIR/test-should-panic-failed-show-span.rs:14:5:
+thread 'should_panic_with_any_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:14:5:
 Panic!
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
-thread 'should_panic_with_message' panicked at $DIR/test-should-panic-failed-show-span.rs:20:5:
+thread 'should_panic_with_message' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:20:5:
 message
 
-thread 'should_panic_with_substring_panics_with_incorrect_string' panicked at $DIR/test-should-panic-failed-show-span.rs:38:5:
+thread 'should_panic_with_substring_panics_with_incorrect_string' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:38:5:
 ZOMGWTFBBQ
 
-thread 'should_panic_with_substring_panics_with_non_string_value' panicked at $DIR/test-should-panic-failed-show-span.rs:45:5:
+thread 'should_panic_with_substring_panics_with_non_string_value' ($TID) panicked at $DIR/test-should-panic-failed-show-span.rs:45:5:
 Box<dyn Any>
diff --git a/tests/ui/test-attrs/test-thread-capture.run.stdout b/tests/ui/test-attrs/test-thread-capture.run.stdout
index f9b9757f861..bea3dcb1041 100644
--- a/tests/ui/test-attrs/test-thread-capture.run.stdout
+++ b/tests/ui/test-attrs/test-thread-capture.run.stdout
@@ -11,7 +11,7 @@ fie
 foe
 fum
 
-thread 'thready_fail' panicked at $DIR/test-thread-capture.rs:32:5:
+thread 'thready_fail' ($TID) panicked at $DIR/test-thread-capture.rs:32:5:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
diff --git a/tests/ui/test-attrs/test-thread-nocapture.run.stderr b/tests/ui/test-attrs/test-thread-nocapture.run.stderr
index 59560015fca..b9905b0c2f9 100644
--- a/tests/ui/test-attrs/test-thread-nocapture.run.stderr
+++ b/tests/ui/test-attrs/test-thread-nocapture.run.stderr
@@ -1,4 +1,4 @@
 
-thread 'thready_fail' panicked at $DIR/test-thread-nocapture.rs:32:5:
+thread 'thready_fail' ($TID) panicked at $DIR/test-thread-nocapture.rs:32:5:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs
index 1b2558c724b..9ce0a4a555a 100644
--- a/tests/ui/track-diagnostics/track.rs
+++ b/tests/ui/track-diagnostics/track.rs
@@ -13,6 +13,11 @@
 // top of this file are present, then assume all args are present.
 //@ normalize-stderr: "note: compiler flags: .*-Z ui-testing.*-Z track-diagnostics" -> "note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics"
 
+// FIXME: this tests a crash in rustc. For stage1, rustc is built with the downloaded standard
+// library which doesn't yet print the thread ID. Normalization can be removed at the stage bump.
+// For the grep: cfg(bootstrap)
+//@normalize-stderr: "thread 'rustc' panicked" -> "thread 'rustc' ($$TID) panicked"
+
 fn main() {
     break rust
     //~^ ERROR cannot find value `rust` in this scope
diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr
index f82764958d4..bc04ded379d 100644
--- a/tests/ui/track-diagnostics/track.stderr
+++ b/tests/ui/track-diagnostics/track.stderr
@@ -27,7 +27,7 @@ LL |     break rust
    = note: compiler flags: ... -Z ui-testing ... -Z track-diagnostics
 
 
-thread 'rustc' panicked at compiler/rustc_hir_typeck/src/lib.rs:LL:CC:
+thread 'rustc' ($TID) panicked at compiler/rustc_hir_typeck/src/lib.rs:LL:CC:
 Box<dyn Any>
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs
index 6f0e3c55fbb..f297a5773cb 100644
--- a/tests/ui/treat-err-as-bug/err.rs
+++ b/tests/ui/treat-err-as-bug/err.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Ztreat-err-as-bug
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*:\n.*\n" -> ""
 //@ rustc-env:RUST_BACKTRACE=0
 
 #![crate_type = "rlib"]
diff --git a/tests/ui/treat-err-as-bug/span_delayed_bug.rs b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
index 4681a8fc1ee..ff5a595899a 100644
--- a/tests/ui/treat-err-as-bug/span_delayed_bug.rs
+++ b/tests/ui/treat-err-as-bug/span_delayed_bug.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*:\n.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*:\n.*\n" -> ""
 //@ rustc-env:RUST_BACKTRACE=0
 
 #![feature(rustc_attrs)]
diff --git a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
index c28fda6f91a..ff99ac98926 100644
--- a/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
+++ b/tests/ui/type/pattern_types/bad_const_generics_args_on_const_param.rs
@@ -1,7 +1,7 @@
 //@known-bug: #127972
 //@ failure-status: 101
 //@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
+//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""
 //@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
 //@ rustc-env:RUST_BACKTRACE=0