@@ -26,9 +26,6 @@ use serde::{Deserialize, Serialize};
26
26
pub struct Backtrace {
27
27
// Frames here are listed from top-to-bottom of the stack
28
28
frames : Vec < BacktraceFrame > ,
29
- // The index we believe is the actual start of the backtrace, omitting
30
- // frames like `Backtrace::new` and `backtrace::trace`.
31
- actual_start_index : usize ,
32
29
}
33
30
34
31
fn _assert_send_sync ( ) {
@@ -86,6 +83,27 @@ impl Frame {
86
83
} => module_base_address. map ( |addr| addr as * mut c_void ) ,
87
84
}
88
85
}
86
+
87
+ /// Resolve all addresses in the frame to their symbolic names.
88
+ fn resolve_symbols ( & self ) -> Vec < BacktraceSymbol > {
89
+ let mut symbols = Vec :: new ( ) ;
90
+ let sym = |symbol : & Symbol | {
91
+ symbols. push ( BacktraceSymbol {
92
+ name : symbol. name ( ) . map ( |m| m. as_bytes ( ) . to_vec ( ) ) ,
93
+ addr : symbol. addr ( ) . map ( |a| a as usize ) ,
94
+ filename : symbol. filename ( ) . map ( |m| m. to_owned ( ) ) ,
95
+ lineno : symbol. lineno ( ) ,
96
+ colno : symbol. colno ( ) ,
97
+ } ) ;
98
+ } ;
99
+ match * self {
100
+ Frame :: Raw ( ref f) => resolve_frame ( f, sym) ,
101
+ Frame :: Deserialized { ip, .. } => {
102
+ resolve ( ip as * mut c_void , sym) ;
103
+ }
104
+ }
105
+ symbols
106
+ }
89
107
}
90
108
91
109
/// Captured version of a symbol in a backtrace.
@@ -172,23 +190,22 @@ impl Backtrace {
172
190
173
191
fn create ( ip : usize ) -> Backtrace {
174
192
let mut frames = Vec :: new ( ) ;
175
- let mut actual_start_index = None ;
176
193
trace ( |frame| {
177
194
frames. push ( BacktraceFrame {
178
195
frame : Frame :: Raw ( frame. clone ( ) ) ,
179
196
symbols : None ,
180
197
} ) ;
181
198
182
- if frame. symbol_address ( ) as usize == ip && actual_start_index. is_none ( ) {
183
- actual_start_index = Some ( frames. len ( ) ) ;
199
+ // clear inner frames, and start with call site.
200
+ if frame. symbol_address ( ) as usize == ip {
201
+ frames. clear ( ) ;
184
202
}
203
+
185
204
true
186
205
} ) ;
206
+ frames. shrink_to_fit ( ) ;
187
207
188
- Backtrace {
189
- frames,
190
- actual_start_index : actual_start_index. unwrap_or ( 0 ) ,
191
- }
208
+ Backtrace { frames }
192
209
}
193
210
194
211
/// Returns the frames from when this backtrace was captured.
@@ -202,7 +219,7 @@ impl Backtrace {
202
219
/// This function requires the `std` feature of the `backtrace` crate to be
203
220
/// enabled, and the `std` feature is enabled by default.
204
221
pub fn frames ( & self ) -> & [ BacktraceFrame ] {
205
- & self . frames [ self . actual_start_index .. ]
222
+ self . frames . as_slice ( )
206
223
}
207
224
208
225
/// If this backtrace was created from `new_unresolved` then this function
@@ -216,51 +233,28 @@ impl Backtrace {
216
233
/// This function requires the `std` feature of the `backtrace` crate to be
217
234
/// enabled, and the `std` feature is enabled by default.
218
235
pub fn resolve ( & mut self ) {
219
- for frame in self . frames . iter_mut ( ) . filter ( |f| f. symbols . is_none ( ) ) {
220
- let mut symbols = Vec :: new ( ) ;
221
- {
222
- let sym = |symbol : & Symbol | {
223
- symbols. push ( BacktraceSymbol {
224
- name : symbol. name ( ) . map ( |m| m. as_bytes ( ) . to_vec ( ) ) ,
225
- addr : symbol. addr ( ) . map ( |a| a as usize ) ,
226
- filename : symbol. filename ( ) . map ( |m| m. to_owned ( ) ) ,
227
- lineno : symbol. lineno ( ) ,
228
- colno : symbol. colno ( ) ,
229
- } ) ;
230
- } ;
231
- match frame. frame {
232
- Frame :: Raw ( ref f) => resolve_frame ( f, sym) ,
233
- Frame :: Deserialized { ip, .. } => {
234
- resolve ( ip as * mut c_void , sym) ;
235
- }
236
- }
237
- }
238
- frame. symbols = Some ( symbols) ;
239
- }
236
+ self . frames . iter_mut ( ) . for_each ( BacktraceFrame :: resolve) ;
240
237
}
241
238
}
242
239
243
240
impl From < Vec < BacktraceFrame > > for Backtrace {
244
241
fn from ( frames : Vec < BacktraceFrame > ) -> Self {
245
- Backtrace {
246
- frames,
247
- actual_start_index : 0 ,
248
- }
242
+ Backtrace { frames }
249
243
}
250
244
}
251
245
252
246
impl From < crate :: Frame > for BacktraceFrame {
253
- fn from ( frame : crate :: Frame ) -> BacktraceFrame {
247
+ fn from ( frame : crate :: Frame ) -> Self {
254
248
BacktraceFrame {
255
249
frame : Frame :: Raw ( frame) ,
256
250
symbols : None ,
257
251
}
258
252
}
259
253
}
260
254
261
- impl Into < Vec < BacktraceFrame > > for Backtrace {
262
- fn into ( self ) -> Vec < BacktraceFrame > {
263
- self . frames
255
+ impl From < Backtrace > for Vec < BacktraceFrame > {
256
+ fn from ( bt : Backtrace ) -> Self {
257
+ bt . frames
264
258
}
265
259
}
266
260
@@ -314,6 +308,20 @@ impl BacktraceFrame {
314
308
pub fn symbols ( & self ) -> & [ BacktraceSymbol ] {
315
309
self . symbols . as_ref ( ) . map ( |s| & s[ ..] ) . unwrap_or ( & [ ] )
316
310
}
311
+
312
+ /// Resolve all addresses in this frame to their symbolic names.
313
+ ///
314
+ /// If this frame has been previously resolved, this function does nothing.
315
+ ///
316
+ /// # Required features
317
+ ///
318
+ /// This function requires the `std` feature of the `backtrace` crate to be
319
+ /// enabled, and the `std` feature is enabled by default.
320
+ pub fn resolve ( & mut self ) {
321
+ if self . symbols . is_none ( ) {
322
+ self . symbols = Some ( self . frame . resolve_symbols ( ) ) ;
323
+ }
324
+ }
317
325
}
318
326
319
327
impl BacktraceSymbol {
@@ -370,11 +378,10 @@ impl BacktraceSymbol {
370
378
371
379
impl fmt:: Debug for Backtrace {
372
380
fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
373
- let full = fmt. alternate ( ) ;
374
- let ( frames, style) = if full {
375
- ( & self . frames [ ..] , PrintFmt :: Full )
381
+ let style = if fmt. alternate ( ) {
382
+ PrintFmt :: Full
376
383
} else {
377
- ( & self . frames [ self . actual_start_index .. ] , PrintFmt :: Short )
384
+ PrintFmt :: Short
378
385
} ;
379
386
380
387
// When printing paths we try to strip the cwd if it exists, otherwise
@@ -385,7 +392,7 @@ impl fmt::Debug for Backtrace {
385
392
let mut print_path =
386
393
move |fmt : & mut fmt:: Formatter < ' _ > , path : crate :: BytesOrWideString < ' _ > | {
387
394
let path = path. into_path_buf ( ) ;
388
- if !full {
395
+ if style == PrintFmt :: Full {
389
396
if let Ok ( cwd) = & cwd {
390
397
if let Ok ( suffix) = path. strip_prefix ( cwd) {
391
398
return fmt:: Display :: fmt ( & suffix. display ( ) , fmt) ;
@@ -397,7 +404,7 @@ impl fmt::Debug for Backtrace {
397
404
398
405
let mut f = BacktraceFmt :: new ( fmt, style, & mut print_path) ;
399
406
f. add_context ( ) ?;
400
- for frame in frames {
407
+ for frame in & self . frames {
401
408
f. frame ( ) . backtrace_frame ( frame) ?;
402
409
}
403
410
f. finish ( ) ?;
0 commit comments