From 0727b6ad0db5876910291f9e20cc66b730cde6e1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 24 Mar 2024 09:40:07 +0100 Subject: [PATCH] panic-in-panic-hook: formatting a message that's just a string is risk-free --- library/std/src/lib.rs | 1 + library/std/src/panicking.rs | 14 +++++++++----- tests/ui/panics/panic-in-message-fmt.run.stderr | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c457c39e0c11c..dc5a8704498d5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -328,6 +328,7 @@ #![feature(float_gamma)] #![feature(float_minimum_maximum)] #![feature(float_next_up_down)] +#![feature(fmt_internals)] #![feature(generic_nonzero)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index e6e1d32fa54f8..31dbe86b66c70 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -391,6 +391,7 @@ pub mod panic_count { pub fn increase(run_panic_hook: bool) -> Option { let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed); if global_count & ALWAYS_ABORT_FLAG != 0 { + // Do *not* access thread-local state, we might be after a `fork`. return Some(MustAbort::AlwaysAbort); } @@ -744,11 +745,14 @@ fn rust_panic_with_hook( if let Some(must_abort) = must_abort { match must_abort { panic_count::MustAbort::PanicInHook => { - // Don't try to print the message in this case - // - perhaps that is causing the recursive panics. + // Don't try to format the message in this case, perhaps that is causing the + // recursive panics. However if the message is just a string, no user-defined + // code is involved in printing it, so that is risk-free. + let msg_str = message.and_then(|m| m.as_str()).map(|m| [m]); + let message = msg_str.as_ref().map(|m| fmt::Arguments::new_const(m)); let panicinfo = PanicInfo::internal_constructor( - None, // no message - location, // but we want to show the location! + message.as_ref(), + location, can_unwind, force_no_backtrace, ); @@ -756,7 +760,7 @@ fn rust_panic_with_hook( } panic_count::MustAbort::AlwaysAbort => { // Unfortunately, this does not print a backtrace, because creating - // a `Backtrace` will allocate, which we must to avoid here. + // a `Backtrace` will allocate, which we must avoid here. let panicinfo = PanicInfo::internal_constructor( message, location, diff --git a/tests/ui/panics/panic-in-message-fmt.run.stderr b/tests/ui/panics/panic-in-message-fmt.run.stderr index c3a5733c8ae3f..46829c33a5466 100644 --- a/tests/ui/panics/panic-in-message-fmt.run.stderr +++ b/tests/ui/panics/panic-in-message-fmt.run.stderr @@ -1,2 +1,3 @@ panicked at $DIR/panic-in-message-fmt.rs:18:9: +not yet implemented thread panicked while processing panic. aborting.