@@ -7,6 +7,7 @@ use crate::io;
7
7
use crate :: borrow:: Cow ;
8
8
use crate :: io:: prelude:: * ;
9
9
use crate :: path:: { self , Path , PathBuf } ;
10
+ use crate :: sync:: atomic:: { self , Ordering } ;
10
11
use crate :: sys:: mutex:: Mutex ;
11
12
12
13
use backtrace_rs:: { BacktraceFmt , BytesOrWideString , PrintFmt } ;
@@ -115,8 +116,10 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
115
116
Ok ( ( ) )
116
117
}
117
118
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) ) ]
120
123
pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> T
121
124
where
122
125
F : FnOnce ( ) -> T ,
@@ -126,42 +129,49 @@ where
126
129
f ( )
127
130
}
128
131
132
+ pub enum RustBacktrace {
133
+ Print ( PrintFmt ) ,
134
+ Disabled ,
135
+ RuntimeDisabled ,
136
+ }
137
+
129
138
// For now logging is turned off by default, and this function checks to see
130
139
// 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
+ }
133
147
134
148
// Setting environment variables for Fuchsia components isn't a standard
135
149
// or easily supported workflow. For now, always display backtraces.
136
150
if cfg ! ( target_os = "fuchsia" ) {
137
- return Some ( PrintFmt :: Full ) ;
151
+ return RustBacktrace :: Print ( PrintFmt :: Full ) ;
138
152
}
139
153
140
154
static ENABLED : atomic:: AtomicIsize = atomic:: AtomicIsize :: new ( 0 ) ;
141
155
match ENABLED . load ( Ordering :: SeqCst ) {
142
156
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 ) ,
146
160
}
147
161
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
165
175
}
166
176
167
177
/// Prints the filename of the backtrace frame.
0 commit comments