Skip to content

Commit 680e2b7

Browse files
committed
Ignore more frames on backtrace unwinding.
Correctly handles panics in threads and tests. First, the frames after `__rust_maybe_catch_panic` are discarded, then it uses a blacklist that does some more fine-tuning. Since frames after the call to `__rust_maybe_catch_panic` seem to be platform-independant, `BAD_PREFIXES_BOTTOM` could probably be cleaned a bit. Fixes rust-lang#40201
1 parent 4be034e commit 680e2b7

File tree

1 file changed

+30
-3
lines changed

1 file changed

+30
-3
lines changed

src/libstd/sys_common/backtrace.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,21 @@ fn filter_frames(frames: &[Frame],
148148
"__scrt_common_main_seh",
149149
"_ZN4drop",
150150
"mingw_set_invalid_parameter_handler",
151+
"_ZN4core3ops6FnOnce9call_once",
152+
"ZN4core3ops6FnOnce9call_once",
153+
"core::ops::FnOnce::call_once",
154+
155+
// tests
156+
"_ZN91_$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..FnOnce$LT$$LP$$RP$$GT$$GT$9call_once",
157+
"ZN91_$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..FnOnce$LT$$LP$$RP$$GT$$GT$9call_once",
158+
"<std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once",
159+
"_ZN4test8run_test",
160+
"ZN4test8run_test",
161+
"test::run_test",
162+
"_ZN42_$LT$F$u20$as$u20$test..FnBox$LT$T$GT$$GT$8call_box",
163+
"ZN42_$LT$F$u20$as$u20$test..FnBox$LT$T$GT$$GT$8call_box",
164+
"<F as test::FnBox<T>>::call_box",
165+
151166
];
152167

153168
let is_good_frame = |frame: Frame, bad_prefixes: &[&str]| {
@@ -164,11 +179,23 @@ fn filter_frames(frames: &[Frame],
164179
let skipped_before = frames.iter().position(|frame| {
165180
is_good_frame(*frame, BAD_PREFIXES_TOP)
166181
}).unwrap_or(frames.len());
167-
let skipped_after = frames[skipped_before..].iter().rev().position(|frame| {
182+
let idx_catch_panic = skipped_before + frames[skipped_before..].iter().position(|frame| {
183+
let mut is_rmcp = false;
184+
let _ = resolve_symname(*frame, |symname| {
185+
if let Some(mangled_symbol_name) = symname {
186+
if mangled_symbol_name == "__rust_maybe_catch_panic" {
187+
is_rmcp = true;
188+
}
189+
}
190+
Ok(())
191+
}, context);
192+
is_rmcp
193+
}).unwrap_or(0);
194+
let skipped_after = frames.len() - idx_catch_panic + frames[skipped_before..idx_catch_panic].iter().rev().position(|frame| {
168195
is_good_frame(*frame, BAD_PREFIXES_BOTTOM)
169-
}).unwrap_or(frames.len() - skipped_before);
196+
}).unwrap_or(0);
170197

171-
if skipped_before + skipped_after == frames.len() {
198+
if skipped_before + skipped_after >= frames.len() {
172199
// Avoid showing completely empty backtraces
173200
return (0, 0);
174201
}

0 commit comments

Comments
 (0)