@@ -105,38 +105,102 @@ use crate::sys_common::backtrace::{lock, output_filename};
105
105
use crate :: vec:: Vec ;
106
106
107
107
pub use core:: backtrace:: Backtrace ;
108
+ pub use core:: backtrace:: BacktraceStatus ;
109
+ use core:: backtrace:: RawBacktrace ;
110
+
111
+ /// Returns whether backtrace captures are enabled through environment
112
+ /// variables.
113
+ #[ export_name = "__rust_backtrace_enabled" ]
114
+ pub fn enabled ( ) -> bool {
115
+ // Cache the result of reading the environment variables to make
116
+ // backtrace captures speedy, because otherwise reading environment
117
+ // variables every time can be somewhat slow.
118
+ static ENABLED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
119
+ match ENABLED . load ( SeqCst ) {
120
+ 0 => { }
121
+ 1 => return false ,
122
+ _ => return true ,
123
+ }
124
+ let enabled = match env:: var ( "RUST_LIB_BACKTRACE" ) {
125
+ Ok ( s) => s != "0" ,
126
+ Err ( _) => match env:: var ( "RUST_BACKTRACE" ) {
127
+ Ok ( s) => s != "0" ,
128
+ Err ( _) => false ,
129
+ } ,
130
+ } ;
131
+ ENABLED . store ( enabled as usize + 1 , SeqCst ) ;
132
+ enabled
133
+ }
134
+
135
+ // Capture a backtrace which start just before the function addressed by
136
+ // `ip`
137
+ #[ export_name = "__rust_backtrace_create" ]
138
+ ///
139
+ pub fn create ( ip : usize ) -> * mut dyn RawBacktrace {
140
+ // SAFETY: We don't attempt to lock this reentrantly.
141
+ let _lock = unsafe { lock ( ) } ;
142
+ let mut frames = Vec :: new ( ) ;
143
+ let mut actual_start = None ;
144
+ unsafe {
145
+ backtrace_rs:: trace_unsynchronized ( |frame| {
146
+ frames. push ( BacktraceFrame {
147
+ frame : RawFrame :: Actual ( frame. clone ( ) ) ,
148
+ symbols : Vec :: new ( ) ,
149
+ } ) ;
150
+ if frame. symbol_address ( ) as usize == ip && actual_start. is_none ( ) {
151
+ actual_start = Some ( frames. len ( ) ) ;
152
+ }
153
+ true
154
+ } ) ;
155
+ }
156
+
157
+ // If no frames came out assume that this is an unsupported platform
158
+ // since `backtrace` doesn't provide a way of learning this right now,
159
+ // and this should be a good enough approximation.
160
+ let inner = if frames. is_empty ( ) {
161
+ Inner :: Unsupported
162
+ } else {
163
+ Inner :: Captured ( LazilyResolvedCapture :: new ( Capture {
164
+ actual_start : actual_start. unwrap_or ( 0 ) ,
165
+ frames,
166
+ resolved : false ,
167
+ } ) )
168
+ } ;
169
+
170
+ let bt: Box < dyn RawBacktrace > = Box :: new ( StdBacktrace { inner } ) ;
171
+ Box :: into_raw ( bt)
172
+ }
173
+
174
+ /// Returns the status of this backtrace, indicating whether this backtrace
175
+ /// request was unsupported, disabled, or a stack trace was actually
176
+ /// captured.
177
+ #[ export_name = "__rust_backtrace_status" ]
178
+ pub fn status ( _backtrace : * mut dyn RawBacktrace ) -> BacktraceStatus {
179
+ todo ! ( )
180
+ // match backtrace.inner {
181
+ // Inner::Unsupported => BacktraceStatus::Unsupported,
182
+ // Inner::Captured(_) => BacktraceStatus::Captured,
183
+ // }
184
+ }
108
185
109
186
/// A captured OS thread stack backtrace.
110
187
///
111
188
/// This type represents a stack backtrace for an OS thread captured at a
112
189
/// previous point in time. In some instances the `Backtrace` type may
113
190
/// internally be empty due to configuration. For more information see
114
191
/// `Backtrace::capture`.
115
- struct BacktraceImpl {
192
+ struct StdBacktrace {
116
193
inner : Inner ,
117
194
}
118
195
119
- impl core:: backtrace:: RawBacktraceImpl for BacktraceImpl { }
120
-
121
- /// The current status of a backtrace, indicating whether it was captured or
122
- /// whether it is empty for some other reason.
123
- #[ non_exhaustive]
124
- #[ derive( Debug , PartialEq , Eq ) ]
125
- pub enum BacktraceStatus {
126
- /// Capturing a backtrace is not supported, likely because it's not
127
- /// implemented for the current platform.
128
- Unsupported ,
129
- /// Capturing a backtrace has been disabled through either the
130
- /// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
131
- Disabled ,
132
- /// A backtrace has been captured and the `Backtrace` should print
133
- /// reasonable information when rendered.
134
- Captured ,
196
+ impl RawBacktrace for StdBacktrace {
197
+ unsafe fn drop_and_free ( self : * mut Self ) {
198
+ todo ! ( )
199
+ }
135
200
}
136
201
137
202
enum Inner {
138
203
Unsupported ,
139
- Disabled ,
140
204
Captured ( LazilyResolvedCapture ) ,
141
205
}
142
206
@@ -148,7 +212,7 @@ struct Capture {
148
212
149
213
fn _assert_send_sync ( ) {
150
214
fn _assert < T : Send + Sync > ( ) { }
151
- _assert :: < Backtrace > ( ) ;
215
+ _assert :: < StdBacktrace > ( ) ;
152
216
}
153
217
154
218
/// A single frame of a backtrace.
@@ -177,11 +241,10 @@ enum BytesOrWide {
177
241
Wide ( Vec < u16 > ) ,
178
242
}
179
243
180
- impl fmt:: Debug for BacktraceImpl {
244
+ impl fmt:: Debug for StdBacktrace {
181
245
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
182
246
let capture = match & self . inner {
183
247
Inner :: Unsupported => return fmt. write_str ( "<unsupported>" ) ,
184
- Inner :: Disabled => return fmt. write_str ( "<disabled>" ) ,
185
248
Inner :: Captured ( c) => c. force ( ) ,
186
249
} ;
187
250
@@ -251,136 +314,18 @@ impl fmt::Debug for BytesOrWide {
251
314
}
252
315
}
253
316
254
- impl Backtrace {
255
- /// Returns whether backtrace captures are enabled through environment
256
- /// variables.
257
- fn enabled ( ) -> bool {
258
- // Cache the result of reading the environment variables to make
259
- // backtrace captures speedy, because otherwise reading environment
260
- // variables every time can be somewhat slow.
261
- static ENABLED : AtomicUsize = AtomicUsize :: new ( 0 ) ;
262
- match ENABLED . load ( SeqCst ) {
263
- 0 => { }
264
- 1 => return false ,
265
- _ => return true ,
266
- }
267
- let enabled = match env:: var ( "RUST_LIB_BACKTRACE" ) {
268
- Ok ( s) => s != "0" ,
269
- Err ( _) => match env:: var ( "RUST_BACKTRACE" ) {
270
- Ok ( s) => s != "0" ,
271
- Err ( _) => false ,
272
- } ,
273
- } ;
274
- ENABLED . store ( enabled as usize + 1 , SeqCst ) ;
275
- enabled
276
- }
277
-
278
- /// Capture a stack backtrace of the current thread.
279
- ///
280
- /// This function will capture a stack backtrace of the current OS thread of
281
- /// execution, returning a `Backtrace` type which can be later used to print
282
- /// the entire stack trace or render it to a string.
283
- ///
284
- /// This function will be a noop if the `RUST_BACKTRACE` or
285
- /// `RUST_LIB_BACKTRACE` backtrace variables are both not set. If either
286
- /// environment variable is set and enabled then this function will actually
287
- /// capture a backtrace. Capturing a backtrace can be both memory intensive
288
- /// and slow, so these environment variables allow liberally using
289
- /// `Backtrace::capture` and only incurring a slowdown when the environment
290
- /// variables are set.
291
- ///
292
- /// To forcibly capture a backtrace regardless of environment variables, use
293
- /// the `Backtrace::force_capture` function.
294
- #[ inline( never) ] // want to make sure there's a frame here to remove
295
- pub fn capture ( ) -> Backtrace {
296
- if !Backtrace :: enabled ( ) {
297
- return Backtrace { inner : Inner :: Disabled } ;
298
- }
299
- Backtrace :: create ( Backtrace :: capture as usize )
300
- }
301
-
302
- /// Forcibly captures a full backtrace, regardless of environment variable
303
- /// configuration.
304
- ///
305
- /// This function behaves the same as `capture` except that it ignores the
306
- /// values of the `RUST_BACKTRACE` and `RUST_LIB_BACKTRACE` environment
307
- /// variables, always capturing a backtrace.
308
- ///
309
- /// Note that capturing a backtrace can be an expensive operation on some
310
- /// platforms, so this should be used with caution in performance-sensitive
311
- /// parts of code.
312
- #[ inline( never) ] // want to make sure there's a frame here to remove
313
- pub fn force_capture ( ) -> Backtrace {
314
- Backtrace :: create ( Backtrace :: force_capture as usize )
315
- }
316
-
317
- /// Forcibly captures a disabled backtrace, regardless of environment
318
- /// variable configuration.
319
- pub const fn disabled ( ) -> Backtrace {
320
- Backtrace { inner : Inner :: Disabled }
321
- }
322
-
323
- // Capture a backtrace which start just before the function addressed by
324
- // `ip`
325
- fn create ( ip : usize ) -> Backtrace {
326
- // SAFETY: We don't attempt to lock this reentrantly.
327
- let _lock = unsafe { lock ( ) } ;
328
- let mut frames = Vec :: new ( ) ;
329
- let mut actual_start = None ;
330
- unsafe {
331
- backtrace_rs:: trace_unsynchronized ( |frame| {
332
- frames. push ( BacktraceFrame {
333
- frame : RawFrame :: Actual ( frame. clone ( ) ) ,
334
- symbols : Vec :: new ( ) ,
335
- } ) ;
336
- if frame. symbol_address ( ) as usize == ip && actual_start. is_none ( ) {
337
- actual_start = Some ( frames. len ( ) ) ;
338
- }
339
- true
340
- } ) ;
341
- }
342
-
343
- // If no frames came out assume that this is an unsupported platform
344
- // since `backtrace` doesn't provide a way of learning this right now,
345
- // and this should be a good enough approximation.
346
- let inner = if frames. is_empty ( ) {
347
- Inner :: Unsupported
348
- } else {
349
- Inner :: Captured ( LazilyResolvedCapture :: new ( Capture {
350
- actual_start : actual_start. unwrap_or ( 0 ) ,
351
- frames,
352
- resolved : false ,
353
- } ) )
354
- } ;
355
-
356
- Backtrace { inner }
357
- }
358
-
359
- /// Returns the status of this backtrace, indicating whether this backtrace
360
- /// request was unsupported, disabled, or a stack trace was actually
361
- /// captured.
362
- pub fn status ( & self ) -> BacktraceStatus {
363
- match self . inner {
364
- Inner :: Unsupported => BacktraceStatus :: Unsupported ,
365
- Inner :: Disabled => BacktraceStatus :: Disabled ,
366
- Inner :: Captured ( _) => BacktraceStatus :: Captured ,
367
- }
368
- }
369
- }
370
-
371
- impl < ' a > Backtrace {
372
- /// Returns an iterator over the backtrace frames.
373
- #[ unstable( feature = "backtrace_frames" , issue = "79676" ) ]
374
- pub fn frames ( & ' a self ) -> & ' a [ BacktraceFrame ] {
375
- if let Inner :: Captured ( c) = & self . inner { & c. force ( ) . frames } else { & [ ] }
376
- }
377
- }
317
+ // impl<'a> StdBacktrace {
318
+ // /// Returns an iterator over the backtrace frames.
319
+ // #[unstable(feature = "backtrace_frames", issue = "79676")]
320
+ // pub fn frames(&'a self) -> &'a [BacktraceFrame] {
321
+ // if let Inner::Captured(c) = &self.inner { &c.force().frames } else { &[] }
322
+ // }
323
+ // }
378
324
379
- impl fmt:: Display for BacktraceImpl {
325
+ impl fmt:: Display for StdBacktrace {
380
326
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
381
327
let capture = match & self . inner {
382
328
Inner :: Unsupported => return fmt. write_str ( "unsupported backtrace" ) ,
383
- Inner :: Disabled => return fmt. write_str ( "disabled backtrace" ) ,
384
329
Inner :: Captured ( c) => c. force ( ) ,
385
330
} ;
386
331
0 commit comments