diff options
| author | joboet <jonasboettiger@icloud.com> | 2024-08-04 10:32:57 +0200 |
|---|---|---|
| committer | joboet <jonasboettiger@icloud.com> | 2024-08-12 10:08:56 +0200 |
| commit | 8542cd67f0581dbace80f451a90caf9257802cb1 (patch) | |
| tree | 1eb52dcf7fc15de196e8b60181430873bdfeefd2 | |
| parent | b389b0ab72cb0aa9acf4df0ae0c0e12090782da9 (diff) | |
| download | rust-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.rs | 26 |
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)] |
