@@ -26,9 +26,6 @@ use serde::{Deserialize, Serialize};
2626pub struct Backtrace {
2727 // Frames here are listed from top-to-bottom of the stack
2828 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 ,
3229}
3330
3431fn _assert_send_sync ( ) {
@@ -86,6 +83,27 @@ impl Frame {
8683 } => module_base_address. map ( |addr| addr as * mut c_void ) ,
8784 }
8885 }
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+ }
89107}
90108
91109/// Captured version of a symbol in a backtrace.
@@ -172,23 +190,22 @@ impl Backtrace {
172190
173191 fn create ( ip : usize ) -> Backtrace {
174192 let mut frames = Vec :: new ( ) ;
175- let mut actual_start_index = None ;
176193 trace ( |frame| {
177194 frames. push ( BacktraceFrame {
178195 frame : Frame :: Raw ( frame. clone ( ) ) ,
179196 symbols : None ,
180197 } ) ;
181198
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 ( ) ;
184202 }
203+
185204 true
186205 } ) ;
206+ frames. shrink_to_fit ( ) ;
187207
188- Backtrace {
189- frames,
190- actual_start_index : actual_start_index. unwrap_or ( 0 ) ,
191- }
208+ Backtrace { frames }
192209 }
193210
194211 /// Returns the frames from when this backtrace was captured.
@@ -202,7 +219,7 @@ impl Backtrace {
202219 /// This function requires the `std` feature of the `backtrace` crate to be
203220 /// enabled, and the `std` feature is enabled by default.
204221 pub fn frames ( & self ) -> & [ BacktraceFrame ] {
205- & self . frames [ self . actual_start_index .. ]
222+ self . frames . as_slice ( )
206223 }
207224
208225 /// If this backtrace was created from `new_unresolved` then this function
@@ -216,51 +233,28 @@ impl Backtrace {
216233 /// This function requires the `std` feature of the `backtrace` crate to be
217234 /// enabled, and the `std` feature is enabled by default.
218235 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) ;
240237 }
241238}
242239
243240impl From < Vec < BacktraceFrame > > for Backtrace {
244241 fn from ( frames : Vec < BacktraceFrame > ) -> Self {
245- Backtrace {
246- frames,
247- actual_start_index : 0 ,
248- }
242+ Backtrace { frames }
249243 }
250244}
251245
252246impl From < crate :: Frame > for BacktraceFrame {
253- fn from ( frame : crate :: Frame ) -> BacktraceFrame {
247+ fn from ( frame : crate :: Frame ) -> Self {
254248 BacktraceFrame {
255249 frame : Frame :: Raw ( frame) ,
256250 symbols : None ,
257251 }
258252 }
259253}
260254
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
264258 }
265259}
266260
@@ -314,6 +308,20 @@ impl BacktraceFrame {
314308 pub fn symbols ( & self ) -> & [ BacktraceSymbol ] {
315309 self . symbols . as_ref ( ) . map ( |s| & s[ ..] ) . unwrap_or ( & [ ] )
316310 }
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+ }
317325}
318326
319327impl BacktraceSymbol {
@@ -370,11 +378,10 @@ impl BacktraceSymbol {
370378
371379impl fmt:: Debug for Backtrace {
372380 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
376383 } else {
377- ( & self . frames [ self . actual_start_index .. ] , PrintFmt :: Short )
384+ PrintFmt :: Short
378385 } ;
379386
380387 // When printing paths we try to strip the cwd if it exists, otherwise
@@ -385,7 +392,7 @@ impl fmt::Debug for Backtrace {
385392 let mut print_path =
386393 move |fmt : & mut fmt:: Formatter < ' _ > , path : crate :: BytesOrWideString < ' _ > | {
387394 let path = path. into_path_buf ( ) ;
388- if !full {
395+ if style == PrintFmt :: Full {
389396 if let Ok ( cwd) = & cwd {
390397 if let Ok ( suffix) = path. strip_prefix ( cwd) {
391398 return fmt:: Display :: fmt ( & suffix. display ( ) , fmt) ;
@@ -397,7 +404,7 @@ impl fmt::Debug for Backtrace {
397404
398405 let mut f = BacktraceFmt :: new ( fmt, style, & mut print_path) ;
399406 f. add_context ( ) ?;
400- for frame in frames {
407+ for frame in & self . frames {
401408 f. frame ( ) . backtrace_frame ( frame) ?;
402409 }
403410 f. finish ( ) ?;
0 commit comments