@@ -79,8 +79,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
7979
8080 let filtered_frames = & frames[ ..nb_frames - skipped_after] ;
8181 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)
8484 } , & context) ?;
8585 let has_more_filenames = foreach_symbol_fileline ( * frame, |file, line| {
8686 output_fileline ( w, file, line, format)
@@ -105,14 +105,14 @@ fn filter_frames(frames: &[Frame],
105105
106106 let skipped_before = 0 ;
107107
108+ // Look for the first occurence of `mark_start`
109+ // There can be multiple in one backtrace
110+ // Skip all frames after that
108111 let skipped_after = frames. len ( ) - frames. iter ( ) . position ( |frame| {
109112 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 ;
116116 }
117117 Ok ( ( ) )
118118 } , context) ;
@@ -127,13 +127,28 @@ fn filter_frames(frames: &[Frame],
127127 ( skipped_before, skipped_after)
128128}
129129
130+ static MARK_START : fn ( & mut FnMut ( ) ) = mark_start;
130131
131- /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
132+ /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`
132133#[ 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+ #[ cfg( not( target_arch = "asmjs" ) ) ]
137+ unsafe {
138+ asm ! ( "" :: : "memory" : "volatile" ) ; // A dummy statement to prevent tail call optimization
139+ }
140+ }
141+
142+ /// Convenience wrapper for `mark_start`
143+ #[ unstable( feature = "rt" , reason = "this is only exported for use in libtest" , issue = "0" ) ]
144+ pub fn begin_short_backtrace < F : FnOnce ( ) -> R , R > ( f : F ) -> R {
145+ let mut f = Some ( f) ;
146+ let mut r = None ;
147+ mark_start ( & mut || {
148+ let f = f. take ( ) . unwrap ( ) ;
149+ r = Some ( f ( ) ) ;
150+ } ) ;
151+ r. unwrap ( )
137152}
138153
139154/// Controls how the backtrace should be formatted.
0 commit comments