From 8542cd67f0581dbace80f451a90caf9257802cb1 Mon Sep 17 00:00:00 2001 From: joboet Date: Sun, 4 Aug 2024 10:32:57 +0200 Subject: [PATCH] std: do not overwrite style in `get_backtrace_style` If another thread calls `set_backtrace_style` while a `get_backtrace_style` is reading the environment variables, `get_backtrace_style` will overwrite the value. Use an atomic CAS to avoid this. --- library/std/src/panic.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs index 4c496ade81cda..6f0952c41ede5 100644 --- a/library/std/src/panic.rs +++ b/library/std/src/panic.rs @@ -440,13 +440,12 @@ impl BacktraceStyle { } fn from_u8(s: u8) -> Option { - Some(match s { - 0 => return None, - 1 => BacktraceStyle::Short, - 2 => BacktraceStyle::Full, - 3 => BacktraceStyle::Off, - _ => unreachable!(), - }) + match s { + 1 => Some(BacktraceStyle::Short), + 2 => Some(BacktraceStyle::Full), + 3 => Some(BacktraceStyle::Off), + _ => None, + } } } @@ -465,7 +464,7 @@ static SHOULD_CAPTURE: AtomicU8 = AtomicU8::new(0); pub fn set_backtrace_style(style: BacktraceStyle) { if cfg!(feature = "backtrace") { // If the `backtrace` feature of this crate is enabled, set the backtrace style. - SHOULD_CAPTURE.store(style.as_u8(), Ordering::Release); + SHOULD_CAPTURE.store(style.as_u8(), Ordering::Relaxed); } } @@ -498,7 +497,9 @@ pub fn get_backtrace_style() -> Option { // to optimize away callers. return None; } - if let Some(style) = BacktraceStyle::from_u8(SHOULD_CAPTURE.load(Ordering::Acquire)) { + + let current = SHOULD_CAPTURE.load(Ordering::Relaxed); + if let Some(style) = BacktraceStyle::from_u8(current) { return Some(style); } @@ -509,8 +510,11 @@ pub fn get_backtrace_style() -> Option { None if crate::sys::FULL_BACKTRACE_DEFAULT => BacktraceStyle::Full, None => BacktraceStyle::Off, }; - set_backtrace_style(format); - Some(format) + + match SHOULD_CAPTURE.compare_exchange(0, format.as_u8(), Ordering::Relaxed, Ordering::Relaxed) { + Ok(_) => Some(format), + Err(new) => BacktraceStyle::from_u8(new), + } } #[cfg(test)]