@@ -71,7 +71,7 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
71
71
let ( nb_frames, context) = unwind_backtrace ( & mut frames) ?;
72
72
let ( skipped_before, skipped_after) =
73
73
filter_frames ( & frames[ ..nb_frames] , format, & context) ;
74
- if format == PrintFormat :: Short {
74
+ if skipped_before + skipped_after > 0 {
75
75
writeln ! ( w, "note: Some details are omitted, \
76
76
run with `RUST_BACKTRACE=full` for a verbose backtrace.") ?;
77
77
}
@@ -101,50 +101,66 @@ fn filter_frames(frames: &[Frame],
101
101
return ( 0 , 0 ) ;
102
102
}
103
103
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| {
110
145
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 ( ( ) )
121
148
}
122
149
}
123
- Ok ( ( ) )
124
- } , context) ;
150
+ Err ( io:: Error :: from ( io:: ErrorKind :: Other ) )
151
+ } , context) . is_ok ( )
152
+ } ;
125
153
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) ;
130
160
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 ) ;
148
164
}
149
165
150
166
( skipped_before, skipped_after)
0 commit comments