@@ -47,27 +47,27 @@ pub struct Frame {
47
47
const MAX_NB_FRAMES : usize = 100 ;
48
48
49
49
/// Prints the current backtrace.
50
- pub fn print ( w : & mut Write , format : PrintFormat ) -> io:: Result < ( ) > {
50
+ pub fn print ( w : & mut Write , format : PrintFormat , entry_point : usize ) -> io:: Result < ( ) > {
51
51
static LOCK : Mutex = Mutex :: new ( ) ;
52
52
53
53
// Use a lock to prevent mixed output in multithreading context.
54
54
// Some platforms also requires it, like `SymFromAddr` on Windows.
55
55
unsafe {
56
56
LOCK . lock ( ) ;
57
- let res = _print ( w, format) ;
57
+ let res = _print ( w, format, entry_point ) ;
58
58
LOCK . unlock ( ) ;
59
59
res
60
60
}
61
61
}
62
62
63
- fn _print ( w : & mut Write , format : PrintFormat ) -> io:: Result < ( ) > {
63
+ fn _print ( w : & mut Write , format : PrintFormat , entry_point : usize ) -> io:: Result < ( ) > {
64
64
let mut frames = [ Frame {
65
65
exact_position : ptr:: null ( ) ,
66
66
symbol_addr : ptr:: null ( ) ,
67
67
} ; MAX_NB_FRAMES ] ;
68
68
let ( nb_frames, context) = unwind_backtrace ( & mut frames) ?;
69
69
let ( skipped_before, skipped_after) =
70
- filter_frames ( & frames[ ..nb_frames] , format, & context) ;
70
+ filter_frames ( & frames[ ..nb_frames] , format, & context, entry_point ) ;
71
71
if skipped_before + skipped_after > 0 {
72
72
writeln ! ( w, "note: Some details are omitted, \
73
73
run with `RUST_BACKTRACE=full` for a verbose backtrace.") ?;
@@ -76,8 +76,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
76
76
77
77
let filtered_frames = & frames[ ..nb_frames - skipped_after] ;
78
78
for ( index, frame) in filtered_frames. iter ( ) . skip ( skipped_before) . enumerate ( ) {
79
- resolve_symname ( * frame, |symname | {
80
- output ( w, index, * frame, symname , format)
79
+ resolve_symname ( * frame, |syminfo | {
80
+ output ( w, index, * frame, syminfo . map ( |i| i . 0 ) , format)
81
81
} , & context) ?;
82
82
let has_more_filenames = foreach_symbol_fileline ( * frame, |file, line| {
83
83
output_fileline ( w, file, line, format)
@@ -94,27 +94,32 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
94
94
/// backtrace, according to the backtrace format.
95
95
fn filter_frames ( frames : & [ Frame ] ,
96
96
format : PrintFormat ,
97
- context : & BacktraceContext ) -> ( usize , usize )
97
+ context : & BacktraceContext ,
98
+ entry_point : usize ) -> ( usize , usize )
98
99
{
99
100
if format == PrintFormat :: Full {
100
101
return ( 0 , 0 ) ;
101
102
}
102
103
103
- let skipped_before = 0 ;
104
+ let skipped_before = frames. iter ( ) . position ( |frame| {
105
+ let mut addr = None ;
106
+ let _ = resolve_symname ( * frame, |syminfo| {
107
+ addr = syminfo. map ( |a| a. 1 ) ;
108
+ Ok ( ( ) )
109
+ } , context) ;
110
+ addr == Some ( entry_point)
111
+ } ) . map ( |p| p + 1 ) . unwrap_or ( 0 ) ;
104
112
105
- let skipped_after = frames. len ( ) - frames . iter ( ) . position ( |frame| {
113
+ let skipped_after = frames. iter ( ) . rev ( ) . position ( |frame| {
106
114
let mut is_marker = false ;
107
- let _ = resolve_symname ( * frame, |symname| {
108
- if let Some ( mangled_symbol_name) = symname {
109
- // Use grep to find the concerned functions
110
- if mangled_symbol_name. contains ( "__rust_begin_short_backtrace" ) {
111
- is_marker = true ;
112
- }
115
+ let _ = resolve_symname ( * frame, |syminfo| {
116
+ if syminfo. map ( |i| i. 1 ) == Some ( MARK_START . 0 as usize ) {
117
+ is_marker = true ;
113
118
}
114
119
Ok ( ( ) )
115
120
} , context) ;
116
121
is_marker
117
- } ) . unwrap_or ( frames . len ( ) ) ;
122
+ } ) . map ( |p| p + 1 ) . unwrap_or ( 0 ) ;
118
123
119
124
if skipped_before + skipped_after >= frames. len ( ) {
120
125
// Avoid showing completely empty backtraces
@@ -124,13 +129,19 @@ fn filter_frames(frames: &[Frame],
124
129
( skipped_before, skipped_after)
125
130
}
126
131
132
+ #[ derive( Eq , PartialEq ) ]
133
+ struct Function ( * const ( ) ) ;
134
+ unsafe impl Sync for Function { }
135
+
136
+ static MARK_START : Function = Function ( mark_start as * const ( ) ) ;
127
137
128
- /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
138
+ /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`
129
139
#[ inline( never) ]
130
- pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> T
131
- where F : FnOnce ( ) -> T , F : Send + ' static , T : Send + ' static
132
- {
133
- f ( )
140
+ pub fn mark_start ( f : & mut FnMut ( ) ) {
141
+ f ( ) ;
142
+ unsafe {
143
+ asm ! ( "" :: : "memory" : "volatile" ) ; // A dummy statement to prevent tail call optimization
144
+ }
134
145
}
135
146
136
147
/// Controls how the backtrace should be formated.
0 commit comments