-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Ignore more frames on backtrace unwinding. #40264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
680e2b7
2183ef6
dfaed07
c40ea76
33e42a3
d54caab
3353a42
deeaa73
7d667e4
00b991e
5205b8d
8a75b20
03f9940
b36446a
0e16333
e1ca626
d72937d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -104,56 +104,30 @@ fn filter_frames(frames: &[Frame], | |
// We want to filter out frames with some prefixes | ||
// from both top and bottom of the call stack. | ||
static BAD_PREFIXES_TOP: &'static [&'static str] = &[ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove this array entirely? Currently There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What to you think about removing the frames from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's fine to strive to eliminate them, but we shouldn't have such a long list of what to filter. There should be one frame that we look for and if we find it maybe do a few calculations based off that. Substring searching is basically guarantee to go wrong in the future. |
||
"_ZN3std3sys3imp9backtrace", | ||
// std::sys::imp::backtrace | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said before, the |
||
"ZN3std3sys3imp9backtrace", | ||
"std::sys::imp::backtrace", | ||
"_ZN3std10sys_common9backtrace", | ||
// std::sys_common::backtrace | ||
"ZN3std10sys_common9backtrace", | ||
"std::sys_common::backtrace", | ||
"_ZN3std9panicking", | ||
// std::panicking | ||
"ZN3std9panicking", | ||
"std::panicking", | ||
"_ZN4core9panicking", | ||
// core::panicking | ||
"ZN4core9panicking", | ||
"core::panicking", | ||
"_ZN4core6result13unwrap_failed", | ||
// core::result::unwrap_failed | ||
"ZN4core6result13unwrap_failed", | ||
"core::result::unwrap_failed", | ||
|
||
"rust_begin_unwind", | ||
"_ZN4drop", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Er was this added in the previous PR? This definitely seems like something that we shouldn't be dropping, this is just a normal function? |
||
"mingw_set_invalid_parameter_handler", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This and |
||
]; | ||
static BAD_PREFIXES_BOTTOM: &'static [&'static str] = &[ | ||
"_ZN3std9panicking", | ||
"ZN3std9panicking", | ||
"std::panicking", | ||
"_ZN3std5panic", | ||
"ZN3std5panic", | ||
"std::panic", | ||
"_ZN4core9panicking", | ||
"ZN4core9panicking", | ||
"core::panicking", | ||
"_ZN3std2rt10lang_start", | ||
"ZN3std2rt10lang_start", | ||
"std::rt::lang_start", | ||
"panic_unwind::__rust_maybe_catch_panic", | ||
"__rust_maybe_catch_panic", | ||
"_rust_maybe_catch_panic", | ||
"__libc_start_main", | ||
"__rust_try", | ||
"_start", | ||
"main", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
"BaseThreadInitThunk", | ||
"RtlInitializeExceptionChain", | ||
"__scrt_common_main_seh", | ||
"_ZN4drop", | ||
"mingw_set_invalid_parameter_handler", | ||
"__rust_begin_backtrace_binary", | ||
"__rust_begin_backtrace_test", | ||
]; | ||
|
||
let is_good_frame = |frame: Frame, bad_prefixes: &[&str]| { | ||
resolve_symname(frame, |symname| { | ||
if let Some(mangled_symbol_name) = symname { | ||
if !bad_prefixes.iter().any(|s| mangled_symbol_name.starts_with(s)) { | ||
if !bad_prefixes.iter().any(|s| mangled_symbol_name.contains(s)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, some platforms seems to have different behaviours, like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know, but that should be the only cases (no |
||
return Ok(()) | ||
} | ||
} | ||
|
@@ -164,11 +138,21 @@ fn filter_frames(frames: &[Frame], | |
let skipped_before = frames.iter().position(|frame| { | ||
is_good_frame(*frame, BAD_PREFIXES_TOP) | ||
}).unwrap_or(frames.len()); | ||
let skipped_after = frames[skipped_before..].iter().rev().position(|frame| { | ||
is_good_frame(*frame, BAD_PREFIXES_BOTTOM) | ||
}).unwrap_or(frames.len() - skipped_before); | ||
|
||
if skipped_before + skipped_after == frames.len() { | ||
let skipped_after = frames.iter().rev().position(|frame| { | ||
let mut is_rmcp = false; | ||
let _ = resolve_symname(*frame, |symname| { | ||
if let Some(mangled_symbol_name) = symname { | ||
if BAD_PREFIXES_BOTTOM.iter().any(|s| mangled_symbol_name.contains(s)) { | ||
is_rmcp = true; | ||
} | ||
} | ||
Ok(()) | ||
}, context); | ||
is_rmcp | ||
}).map(|x| x + 1 /* also ignore the marker frame */).unwrap_or(0); | ||
|
||
if skipped_before + skipped_after >= frames.len() { | ||
// Avoid showing completely empty backtraces | ||
return (0, 0); | ||
} | ||
|
@@ -198,7 +182,7 @@ pub fn log_enabled() -> Option<PrintFormat> { | |
} | ||
|
||
let val = match env::var_os("RUST_BACKTRACE") { | ||
Some(x) => if &x == "0" { | ||
Some(x) => if &x == "0" || &x == "" { | ||
None | ||
} else if &x == "full" { | ||
Some(PrintFormat::Full) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1363,12 +1363,29 @@ pub fn run_test(opts: &TestOpts, | |
monitor_ch.send((desc, TrMetrics(mm), Vec::new())).unwrap(); | ||
return; | ||
} | ||
DynTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, f), | ||
StaticTestFn(f) => run_test_inner(desc, monitor_ch, opts.nocapture, | ||
Box::new(move |()| f())), | ||
DynTestFn(f) => | ||
run_test_inner(desc, monitor_ch, opts.nocapture, | ||
Box::new(move |()| __rust_begin_backtrace_test_boxfn(f))), | ||
StaticTestFn(f) => | ||
run_test_inner(desc, monitor_ch, opts.nocapture, | ||
Box::new(move |()| __rust_begin_backtrace_test(f))), | ||
} | ||
} | ||
|
||
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. | ||
#[no_mangle] | ||
#[inline(never)] | ||
pub fn __rust_begin_backtrace_test_boxfn(f: Box<FnBox<()>>) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two more unnecessary |
||
f.call_box(()) | ||
} | ||
|
||
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. | ||
#[no_mangle] | ||
#[inline(never)] | ||
pub fn __rust_begin_backtrace_test(f: fn()) { | ||
f() | ||
} | ||
|
||
fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any + Send>>) -> TestResult { | ||
match (&desc.should_panic, task_result) { | ||
(&ShouldPanic::No, Ok(())) | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pub
is not needed hereThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or you can keep this
pub
, add#[doc(hidden)]
and reuse it in libtest.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://play.rust-lang.org/?gist=e7c60682076e24a4f2ad4fe56af59de1&version=stable&backtrace=1
What do you think would be better,
#[ignore(..)]
the warning, or keep it pub and hide the doc?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore.
I've just realized though, since we use
contains
and not exact matching, thenno_mangle
can be just removed most probably.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, even easier ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible, I would follow the example of
rust_panic
and use#[no_mangle]
and#[allow(private_no_mangle_fns)]
:rust/src/libstd/panicking.rs
Lines 574 to 577 in a559452