about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjoboet <jonasboettiger@icloud.com>2024-08-04 10:32:57 +0200
committerjoboet <jonasboettiger@icloud.com>2024-08-12 10:08:56 +0200
commit8542cd67f0581dbace80f451a90caf9257802cb1 (patch)
tree1eb52dcf7fc15de196e8b60181430873bdfeefd2
parentb389b0ab72cb0aa9acf4df0ae0c0e12090782da9 (diff)
downloadrust-8542cd67f0581dbace80f451a90caf9257802cb1.tar.gz
rust-8542cd67f0581dbace80f451a90caf9257802cb1.zip
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.
-rw-r--r--library/std/src/panic.rs26
1 files changed, 15 insertions, 11 deletions
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index 4c496ade81c..6f0952c41ed 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<Self> {
-        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<BacktraceStyle> {
         // 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<BacktraceStyle> {
         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)]