@@ -16,6 +16,8 @@ use io::prelude::*;
16
16
use io;
17
17
use libc;
18
18
use str;
19
+ use core;
20
+ use panicking;
19
21
use sync:: atomic:: { self , Ordering } ;
20
22
use path:: { self , Path } ;
21
23
use sys:: mutex:: Mutex ;
@@ -77,8 +79,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
77
79
78
80
let filtered_frames = & frames[ ..nb_frames - skipped_after] ;
79
81
for ( index, frame) in filtered_frames. iter ( ) . skip ( skipped_before) . enumerate ( ) {
80
- resolve_symname ( * frame, |symname | {
81
- output ( w, index, * frame, symname , format)
82
+ resolve_symname ( * frame, |syminfo | {
83
+ output ( w, index, * frame, syminfo . map ( |i| i . 0 ) , format)
82
84
} , & context) ?;
83
85
let has_more_filenames = foreach_symbol_fileline ( * frame, |file, line| {
84
86
output_fileline ( w, file, line, format)
@@ -101,12 +103,32 @@ fn filter_frames(frames: &[Frame],
101
103
return ( 0 , 0 ) ;
102
104
}
103
105
104
- let skipped_before = 0 ;
106
+ #[ derive( Eq , PartialEq ) ]
107
+ struct Function ( * const ( ) ) ;
108
+ unsafe impl Sync for Function { }
109
+
110
+ static PANIC_FUNCTIONS : & [ Function ] = & [
111
+ Function ( core:: panicking:: panic as * const ( ) ) ,
112
+ Function ( core:: panicking:: panic_bounds_check as * const ( ) ) ,
113
+ Function ( core:: panicking:: panic_fmt as * const ( ) ) ,
114
+ Function ( panicking:: begin_panic_str as * const ( ) ) ,
115
+ Function ( panicking:: begin_panic_fmt as * const ( ) ) ,
116
+ Function ( panicking:: rust_panic_with_hook as * const ( ) ) ,
117
+ ] ;
118
+
119
+ let skipped_before = frames. len ( ) - frames. iter ( ) . rev ( ) . position ( |frame| {
120
+ let mut addr = None ;
121
+ resolve_symname ( * frame, |syminfo| {
122
+ addr = syminfo. map ( |a| a. 1 ) ;
123
+ Ok ( ( ) )
124
+ } , context) . ok ( ) ;
125
+ addr. map ( |a| PANIC_FUNCTIONS . contains ( & Function ( a as * const ( ) ) ) ) . unwrap_or ( false )
126
+ } ) . unwrap_or ( frames. len ( ) ) ;
105
127
106
128
let skipped_after = frames. len ( ) - frames. iter ( ) . position ( |frame| {
107
129
let mut is_marker = false ;
108
- let _ = resolve_symname ( * frame, |symname | {
109
- if let Some ( mangled_symbol_name) = symname {
130
+ let _ = resolve_symname ( * frame, |syminfo | {
131
+ if let Some ( ( mangled_symbol_name, _ ) ) = syminfo {
110
132
// Use grep to find the concerned functions
111
133
if mangled_symbol_name. contains ( "__rust_begin_short_backtrace" ) {
112
134
is_marker = true ;
@@ -125,13 +147,12 @@ fn filter_frames(frames: &[Frame],
125
147
( skipped_before, skipped_after)
126
148
}
127
149
128
-
129
150
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
130
151
#[ inline( never) ]
131
- pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> T
152
+ pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> ( T , usize )
132
153
where F : FnOnce ( ) -> T , F : Send + ' static , T : Send + ' static
133
154
{
134
- f ( )
155
+ ( f ( ) , 0 ) // The number is a dummy return value to prevent tail call optimization
135
156
}
136
157
137
158
/// Controls how the backtrace should be formated.
0 commit comments