@@ -79,8 +79,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
79
79
80
80
let filtered_frames = & frames[ ..nb_frames - skipped_after] ;
81
81
for ( index, frame) in filtered_frames. iter ( ) . skip ( skipped_before) . enumerate ( ) {
82
- resolve_symname ( * frame, |symname | {
83
- output ( w, index, * frame, symname , format)
82
+ resolve_symname ( * frame, |syminfo | {
83
+ output ( w, index, * frame, syminfo . map ( |i| i . 0 ) , format)
84
84
} , & context) ?;
85
85
let has_more_filenames = foreach_symbol_fileline ( * frame, |file, line| {
86
86
output_fileline ( w, file, line, format)
@@ -105,14 +105,14 @@ fn filter_frames(frames: &[Frame],
105
105
106
106
let skipped_before = 0 ;
107
107
108
+ // Look for the first occurence of `mark_start`
109
+ // There can be multiple in one backtrace
110
+ // Skip all frames after that
108
111
let skipped_after = frames. len ( ) - frames. iter ( ) . position ( |frame| {
109
112
let mut is_marker = false ;
110
- let _ = resolve_symname ( * frame, |symname| {
111
- if let Some ( mangled_symbol_name) = symname {
112
- // Use grep to find the concerned functions
113
- if mangled_symbol_name. contains ( "__rust_begin_short_backtrace" ) {
114
- is_marker = true ;
115
- }
113
+ let _ = resolve_symname ( * frame, |syminfo| {
114
+ if syminfo. map ( |i| i. 1 ) == Some ( MARK_START as usize ) {
115
+ is_marker = true ;
116
116
}
117
117
Ok ( ( ) )
118
118
} , context) ;
@@ -127,13 +127,27 @@ fn filter_frames(frames: &[Frame],
127
127
( skipped_before, skipped_after)
128
128
}
129
129
130
+ static MARK_START : fn ( & mut FnMut ( ) ) = mark_start;
130
131
131
- /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
132
+ /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`
132
133
#[ inline( never) ]
133
- pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> T
134
- where F : FnOnce ( ) -> T , F : Send , T : Send
135
- {
136
- f ( )
134
+ fn mark_start ( f : & mut FnMut ( ) ) {
135
+ f ( ) ;
136
+ unsafe {
137
+ asm ! ( "" :: : "memory" : "volatile" ) ; // A dummy statement to prevent tail call optimization
138
+ }
139
+ }
140
+
141
+ /// Convenience wrapper for `mark_start`
142
+ #[ unstable( feature = "rt" , reason = "this is only exported for use in libtest" , issue = "0" ) ]
143
+ pub fn begin_short_backtrace < F : FnOnce ( ) -> R , R > ( f : F ) -> R {
144
+ let mut f = Some ( f) ;
145
+ let mut r = None ;
146
+ mark_start ( & mut || {
147
+ let f = f. take ( ) . unwrap ( ) ;
148
+ r = Some ( f ( ) ) ;
149
+ } ) ;
150
+ r. unwrap ( )
137
151
}
138
152
139
153
/// Controls how the backtrace should be formated.
0 commit comments