Skip to content

Commit 1d06058

Browse files
committed
std: Reduce checks for feature = "backtrace"
This is a stylistic change to libstd to reduce the number of checks of `feature = "backtrace"` now that we unconditionally depend on the `backtrace` crate and rely on it having an empty implementation. otherwise.
1 parent 6ef275e commit 1d06058

File tree

4 files changed

+50
-50
lines changed

4 files changed

+50
-50
lines changed

src/libstd/panicking.rs

+15-19
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ use crate::intrinsics;
1515
use crate::mem;
1616
use crate::ptr;
1717
use crate::raw;
18+
use crate::sync::atomic::{AtomicBool, Ordering};
1819
use crate::sys::stdio::panic_output;
1920
use crate::sys_common::rwlock::RWLock;
20-
use crate::sys_common::{thread_info, util, backtrace};
21+
use crate::sys_common::{thread_info, util};
22+
use crate::sys_common::backtrace::{self, RustBacktrace};
2123
use crate::thread;
2224

2325
#[cfg(not(test))]
@@ -158,16 +160,10 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
158160
fn default_hook(info: &PanicInfo<'_>) {
159161
// If this is a double panic, make sure that we print a backtrace
160162
// for this panic. Otherwise only print it if logging is enabled.
161-
let log_backtrace = if cfg!(feature = "backtrace") {
162-
let panics = update_panic_count(0);
163-
164-
if panics >= 2 {
165-
Some(backtrace_rs::PrintFmt::Full)
166-
} else {
167-
backtrace::log_enabled()
168-
}
163+
let backtrace_env = if update_panic_count(0) >= 2 {
164+
RustBacktrace::Print(backtrace_rs::PrintFmt::Full)
169165
} else {
170-
None
166+
backtrace::rust_backtrace_env()
171167
};
172168

173169
// The current implementation always returns `Some`.
@@ -187,16 +183,16 @@ fn default_hook(info: &PanicInfo<'_>) {
187183
let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
188184
name, msg, location);
189185

190-
if cfg!(feature = "backtrace") {
191-
use crate::sync::atomic::{AtomicBool, Ordering};
192-
193-
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
186+
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
194187

195-
if let Some(format) = log_backtrace {
196-
let _ = backtrace::print(err, format);
197-
} else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
198-
let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
199-
environment variable to display a backtrace.");
188+
match backtrace_env {
189+
RustBacktrace::Print(format) => drop(backtrace::print(err, format)),
190+
RustBacktrace::Disabled => {}
191+
RustBacktrace::RuntimeDisabled => {
192+
if FIRST_PANIC.swap(false, Ordering::SeqCst) {
193+
let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
194+
environment variable to display a backtrace.");
195+
}
200196
}
201197
}
202198
};

src/libstd/rt.rs

-3
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@ fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindS
4444
sys::args::init(argc, argv);
4545

4646
// Let's run some code!
47-
#[cfg(feature = "backtrace")]
4847
let exit_code = panic::catch_unwind(|| {
4948
sys_common::backtrace::__rust_begin_short_backtrace(move || main())
5049
});
51-
#[cfg(not(feature = "backtrace"))]
52-
let exit_code = panic::catch_unwind(move || main());
5350

5451
sys_common::cleanup();
5552
exit_code.unwrap_or(101) as isize

src/libstd/sys_common/backtrace.rs

+35-25
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::io;
77
use crate::borrow::Cow;
88
use crate::io::prelude::*;
99
use crate::path::{self, Path, PathBuf};
10+
use crate::sync::atomic::{self, Ordering};
1011
use crate::sys::mutex::Mutex;
1112

1213
use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
@@ -115,8 +116,10 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
115116
Ok(())
116117
}
117118

118-
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
119-
#[inline(never)]
119+
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
120+
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
121+
/// it's fine to optimize away.
122+
#[cfg_attr(feature = "backtrace", inline(never))]
120123
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
121124
where
122125
F: FnOnce() -> T,
@@ -126,42 +129,49 @@ where
126129
f()
127130
}
128131

132+
pub enum RustBacktrace {
133+
Print(PrintFmt),
134+
Disabled,
135+
RuntimeDisabled,
136+
}
137+
129138
// For now logging is turned off by default, and this function checks to see
130139
// whether the magical environment variable is present to see if it's turned on.
131-
pub fn log_enabled() -> Option<PrintFmt> {
132-
use crate::sync::atomic::{self, Ordering};
140+
pub fn rust_backtrace_env() -> RustBacktrace {
141+
// If the `backtrace` feature of this crate isn't enabled quickly return
142+
// `None` so this can be constant propagated all over the place to turn
143+
// optimize away callers.
144+
if !cfg!(feature = "backtrace") {
145+
return RustBacktrace::Disabled;
146+
}
133147

134148
// Setting environment variables for Fuchsia components isn't a standard
135149
// or easily supported workflow. For now, always display backtraces.
136150
if cfg!(target_os = "fuchsia") {
137-
return Some(PrintFmt::Full);
151+
return RustBacktrace::Print(PrintFmt::Full);
138152
}
139153

140154
static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
141155
match ENABLED.load(Ordering::SeqCst) {
142156
0 => {}
143-
1 => return None,
144-
2 => return Some(PrintFmt::Short),
145-
_ => return Some(PrintFmt::Full),
157+
1 => return RustBacktrace::RuntimeDisabled,
158+
2 => return RustBacktrace::Print(PrintFmt::Short),
159+
_ => return RustBacktrace::Print(PrintFmt::Full),
146160
}
147161

148-
let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
149-
if &x == "0" {
150-
None
151-
} else if &x == "full" {
152-
Some(PrintFmt::Full)
153-
} else {
154-
Some(PrintFmt::Short)
155-
}
156-
});
157-
ENABLED.store(
158-
match val {
159-
Some(v) => v as isize,
160-
None => 1,
161-
},
162-
Ordering::SeqCst,
163-
);
164-
val
162+
let (format, cache) = env::var_os("RUST_BACKTRACE")
163+
.map(|x| {
164+
if &x == "0" {
165+
(RustBacktrace::RuntimeDisabled, 1)
166+
} else if &x == "full" {
167+
(RustBacktrace::Print(PrintFmt::Full), 3)
168+
} else {
169+
(RustBacktrace::Print(PrintFmt::Short), 2)
170+
}
171+
})
172+
.unwrap_or((RustBacktrace::RuntimeDisabled, 1));
173+
ENABLED.store(cache, Ordering::SeqCst);
174+
format
165175
}
166176

167177
/// Prints the filename of the backtrace frame.

src/libstd/thread/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -465,12 +465,9 @@ impl Builder {
465465
}
466466

467467
thread_info::set(imp::guard::current(), their_thread);
468-
#[cfg(feature = "backtrace")]
469468
let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
470469
crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
471470
}));
472-
#[cfg(not(feature = "backtrace"))]
473-
let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
474471
*their_packet.get() = Some(try_result);
475472
};
476473

0 commit comments

Comments
 (0)