about summary refs log tree commit diff
path: root/library/std/src/panicking.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/panicking.rs')
-rw-r--r--library/std/src/panicking.rs8
1 files changed, 6 insertions, 2 deletions
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index ebd05415695..418a855fb72 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -253,16 +253,20 @@ fn default_hook(info: &PanicHookInfo<'_>) {
     let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
 
     let write = |err: &mut dyn crate::io::Write| {
+        // Use a lock to prevent mixed output in multithreading context.
+        // Some platforms also require it when printing a backtrace, like `SymFromAddr` on Windows.
+        let mut lock = backtrace::lock();
         let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
 
         static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
         match backtrace {
+            // SAFETY: we took out a lock just a second ago.
             Some(BacktraceStyle::Short) => {
-                drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Short))
+                drop(lock.print(err, crate::backtrace_rs::PrintFmt::Short))
             }
             Some(BacktraceStyle::Full) => {
-                drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Full))
+                drop(lock.print(err, crate::backtrace_rs::PrintFmt::Full))
             }
             Some(BacktraceStyle::Off) => {
                 if FIRST_PANIC.swap(false, Ordering::Relaxed) {