@@ -13,8 +13,11 @@ use {trace, resolve, SymbolName};
13
13
#[ cfg_attr( feature = "serialize-rustc" , derive( RustcDecodable , RustcEncodable ) ) ]
14
14
#[ cfg_attr( feature = "serialize-serde" , derive( Deserialize , Serialize ) ) ]
15
15
pub struct Backtrace {
16
+ // Frames here are listed from top-to-bottom of the stack
16
17
frames : Vec < BacktraceFrame > ,
17
- ext_index : usize ,
18
+ // The index we believe is the actual start of the backtrace, omitting
19
+ // frames like `Backtrace::new` and `backtrace::trace`.
20
+ actual_start_index : usize ,
18
21
}
19
22
20
23
/// Captured version of a frame in a backtrace.
@@ -60,8 +63,11 @@ impl Backtrace {
60
63
///
61
64
/// let current_backtrace = Backtrace::new();
62
65
/// ```
66
+ #[ inline( never) ] // want to make sure there's a frame here to remove
63
67
pub fn new ( ) -> Backtrace {
64
- Self :: create ( Self :: new as usize ) . resolved ( )
68
+ let mut bt = Self :: create ( Self :: new as usize ) ;
69
+ bt. resolve ( ) ;
70
+ bt
65
71
}
66
72
67
73
/// Similar to `new` except that this does not resolve any symbols, this
@@ -82,15 +88,17 @@ impl Backtrace {
82
88
/// current_backtrace.resolve();
83
89
/// println!("{:?}", current_backtrace); // symbol names now present
84
90
/// ```
91
+ #[ inline( never) ] // want to make sure there's a frame here to remove
85
92
pub fn new_unresolved ( ) -> Backtrace {
86
93
Self :: create ( Self :: new_unresolved as usize )
87
94
}
88
95
89
96
fn create ( ip : usize ) -> Backtrace {
90
- let ip_range: ( usize , usize ) = ( ip, ip + 128 ) ;
97
+ let ip_lo = ip;
98
+ let ip_hi = ip + 128 ;
91
99
92
100
let mut frames = Vec :: new ( ) ;
93
- let mut ext_index = None ;
101
+ let mut actual_start_index = None ;
94
102
trace ( |frame| {
95
103
let ip = frame. ip ( ) as usize ;
96
104
frames. push ( BacktraceFrame {
@@ -99,24 +107,22 @@ impl Backtrace {
99
107
symbols : None ,
100
108
} ) ;
101
109
102
- if cfg ! ( not( all( target_os = "windows" , target_arch = "x86" ) ) ) && ip >= ip_range. 0 && ip <= ip_range. 1 {
103
- ext_index = Some ( frames. len ( ) ) ;
110
+ if cfg ! ( not( all( target_os = "windows" , target_arch = "x86" ) ) ) &&
111
+ ip >= ip_lo &&
112
+ ip <= ip_hi &&
113
+ actual_start_index. is_none ( )
114
+ {
115
+ actual_start_index = Some ( frames. len ( ) ) ;
104
116
}
105
117
true
106
118
} ) ;
107
119
108
120
Backtrace {
109
121
frames,
110
- ext_index : ext_index . unwrap_or ( 0 ) ,
122
+ actual_start_index : actual_start_index . unwrap_or ( 0 ) ,
111
123
}
112
124
}
113
125
114
- #[ inline( always) ]
115
- fn resolved ( mut self ) -> Backtrace {
116
- self . resolve ( ) ;
117
- self
118
- }
119
-
120
126
/// Returns the frames from when this backtrace was captured.
121
127
///
122
128
/// The first entry of this slice is likely the function `Backtrace::new`,
@@ -126,37 +132,6 @@ impl Backtrace {
126
132
& self . frames
127
133
}
128
134
129
- /// Returns the frames from when this backtrace was captured, omitting frames from within this
130
- /// crate itself, if possible (see `ext_index()`)
131
- pub fn ext_frames ( & self ) -> & [ BacktraceFrame ] {
132
- & self . frames [ self . ext_index ..]
133
- }
134
-
135
- /// Returns the index of the first "external" frame (i.e. the call-site of one of the
136
- /// public constructors `new` or `new_unresolved`), if known, `0` otherwise. Backtrace frames
137
- /// up to this index are from within this crate itself, and usually do not present useful
138
- /// information when used from other crates, and as such can be skipped from displaying.
139
- ///
140
- /// This index is used when backtrace is displayed in the default debug format `{:?}`.
141
- /// Full backtrace can be still displayed using alternative debug format `{:#?}`.
142
- ///
143
- /// If this function returns `0`, either debug formats will display full backtrace.
144
- ///
145
- /// # Examples
146
- ///
147
- /// ```
148
- /// use backtrace::Backtrace;
149
- ///
150
- /// let backtrace = Backtrace::new();
151
- /// println!("{:?}", backtrace); // prints backtrace skipping frames from within this crate
152
- ///
153
- /// println!("{:#?}", backtrace); // prints full backtrace
154
- /// ```
155
- /// *Note*: currently this always return `0` on Windows x86 (32-bit) targets
156
- pub fn ext_index ( & self ) -> usize {
157
- self . ext_index
158
- }
159
-
160
135
/// If this backtrace was created from `new_unresolved` then this function
161
136
/// will resolve all addresses in the backtrace to their symbolic names.
162
137
///
@@ -182,7 +157,7 @@ impl From<Vec<BacktraceFrame>> for Backtrace {
182
157
fn from ( frames : Vec < BacktraceFrame > ) -> Self {
183
158
Backtrace {
184
159
frames,
185
- ext_index : 0 ,
160
+ actual_start_index : 0 ,
186
161
}
187
162
}
188
163
}
@@ -247,10 +222,10 @@ impl fmt::Debug for Backtrace {
247
222
write ! ( fmt, "stack backtrace:" ) ?;
248
223
249
224
let iter = if fmt. alternate ( ) {
250
- self . frames ( )
225
+ self . frames . iter ( )
251
226
} else {
252
- self . ext_frames ( )
253
- } . iter ( ) ;
227
+ self . frames [ self . actual_start_index .. ] . iter ( )
228
+ } ;
254
229
255
230
for ( idx, frame) in iter. enumerate ( ) {
256
231
let ip = frame. ip ( ) ;
0 commit comments