@@ -71,7 +71,7 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
7171 let ( nb_frames, context) = unwind_backtrace ( & mut frames) ?;
7272 let ( skipped_before, skipped_after) =
7373 filter_frames ( & frames[ ..nb_frames] , format, & context) ;
74- if format == PrintFormat :: Short {
74+ if skipped_before + skipped_after > 0 {
7575 writeln ! ( w, "note: Some details are omitted, \
7676 run with `RUST_BACKTRACE=full` for a verbose backtrace.") ?;
7777 }
@@ -101,50 +101,66 @@ fn filter_frames(frames: &[Frame],
101101 return ( 0 , 0 ) ;
102102 }
103103
104- let mut skipped_before = 0 ;
105- for ( i, frame) in frames. iter ( ) . enumerate ( ) {
106- skipped_before = i;
107- let mut skip = false ;
108-
109- let _ = resolve_symname ( * frame, |symname| {
104+ // We want to filter out frames with some prefixes
105+ // from both top and bottom of the call stack.
106+ static BAD_PREFIXES_TOP : & ' static [ & ' static str ] = & [
107+ "_ZN3std3sys3imp9backtrace" ,
108+ "ZN3std3sys3imp9backtrace" ,
109+ "_ZN3std10sys_common9backtrace" ,
110+ "ZN3std10sys_common9backtrace" ,
111+ "_ZN3std9panicking" ,
112+ "ZN3std9panicking" ,
113+ "std::panicking" ,
114+ "_ZN4core9panicking" ,
115+ "ZN4core9panicking" ,
116+ "core::panicking" ,
117+ "_ZN4core6result13unwrap_failed" ,
118+ "ZN4core6result13unwrap_failed" ,
119+ "rust_begin_unwind" ,
120+ "_ZN4drop" ,
121+ "mingw_set_invalid_parameter_handler" ,
122+ ] ;
123+ static BAD_PREFIXES_BOTTOM : & ' static [ & ' static str ] = & [
124+ "_ZN3std9panicking" ,
125+ "ZN3std9panicking" ,
126+ "std::panicking" ,
127+ "_ZN4core9panicking" ,
128+ "ZN4core9panicking" ,
129+ "core::panicking" ,
130+ "_ZN3std2rt10lang_start" ,
131+ "ZN3std2rt10lang_start" ,
132+ "__rust_maybe_catch_panic" ,
133+ "_rust_maybe_catch_panic" ,
134+ "__libc_start_main" ,
135+ "__rust_try" ,
136+ "_start" ,
137+ "BaseThreadInitThunk" ,
138+ "__scrt_common_main_seh" ,
139+ "_ZN4drop" ,
140+ "mingw_set_invalid_parameter_handler" ,
141+ ] ;
142+
143+ let is_good_frame = |frame : Frame , bad_prefixes : & [ & str ] | {
144+ resolve_symname ( frame, |symname| {
110145 if let Some ( mangled_symbol_name) = symname {
111- let magics_begin = [
112- "_ZN3std3sys3imp9backtrace" ,
113- "_ZN3std10sys_common9backtrace" ,
114- "_ZN3std9panicking" ,
115- "_ZN4core9panicking" ,
116- "rust_begin_unwind" ,
117- "_ZN4core6result13unwrap_failed" ,
118- ] ;
119- if !magics_begin. iter ( ) . any ( |s| mangled_symbol_name. starts_with ( s) ) {
120- skip = true ;
146+ if !bad_prefixes. iter ( ) . any ( |s| mangled_symbol_name. starts_with ( s) ) {
147+ return Ok ( ( ) )
121148 }
122149 }
123- Ok ( ( ) )
124- } , context) ;
150+ Err ( io:: Error :: from ( io:: ErrorKind :: Other ) )
151+ } , context) . is_ok ( )
152+ } ;
125153
126- if skip {
127- break ;
128- }
129- }
154+ let skipped_before = frames. iter ( ) . position ( |frame| {
155+ is_good_frame ( * frame, BAD_PREFIXES_TOP )
156+ } ) . unwrap_or ( frames. len ( ) ) ;
157+ let skipped_after = frames[ skipped_before..] . iter ( ) . rposition ( |frame| {
158+ is_good_frame ( * frame, BAD_PREFIXES_BOTTOM )
159+ } ) . unwrap_or ( frames. len ( ) - skipped_before) ;
130160
131- let mut skipped_after = 0 ;
132- for ( i, frame) in frames. iter ( ) . rev ( ) . enumerate ( ) {
133- let _ = resolve_symname ( * frame, |symname| {
134- if let Some ( mangled_symbol_name) = symname {
135- let magics_end = [
136- "_ZN3std9panicking3try7do_call" ,
137- "__rust_maybe_catch_panic" ,
138- "__libc_start_main" ,
139- "__rust_try" ,
140- "_start" ,
141- ] ;
142- if magics_end. iter ( ) . any ( |s| mangled_symbol_name. starts_with ( s) ) {
143- skipped_after = i + 1 ;
144- }
145- }
146- Ok ( ( ) )
147- } , context) ;
161+ if skipped_before + skipped_after == frames. len ( ) {
162+ // Avoid showing completely empty backtraces
163+ return ( 0 , 0 ) ;
148164 }
149165
150166 ( skipped_before, skipped_after)
0 commit comments