-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Ignore functions before main and thread entry points in backtraces #47824
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 all commits
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 |
---|---|---|
|
@@ -79,8 +79,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> { | |
|
||
let filtered_frames = &frames[..nb_frames - skipped_after]; | ||
for (index, frame) in filtered_frames.iter().skip(skipped_before).enumerate() { | ||
resolve_symname(*frame, |symname| { | ||
output(w, index, *frame, symname, format) | ||
resolve_symname(*frame, |syminfo| { | ||
output(w, index, *frame, syminfo.map(|i| i.0), format) | ||
}, &context)?; | ||
let has_more_filenames = foreach_symbol_fileline(*frame, |file, line| { | ||
output_fileline(w, file, line, format) | ||
|
@@ -105,14 +105,14 @@ fn filter_frames(frames: &[Frame], | |
|
||
let skipped_before = 0; | ||
|
||
// Look for the first occurence of `mark_start` | ||
// There can be multiple in one backtrace | ||
// Skip all frames after that | ||
let skipped_after = frames.len() - frames.iter().position(|frame| { | ||
let mut is_marker = false; | ||
let _ = resolve_symname(*frame, |symname| { | ||
if let Some(mangled_symbol_name) = symname { | ||
// Use grep to find the concerned functions | ||
if mangled_symbol_name.contains("__rust_begin_short_backtrace") { | ||
is_marker = true; | ||
} | ||
let _ = resolve_symname(*frame, |syminfo| { | ||
if syminfo.map(|i| i.1) == Some(MARK_START as usize) { | ||
is_marker = true; | ||
} | ||
Ok(()) | ||
}, context); | ||
|
@@ -127,13 +127,27 @@ fn filter_frames(frames: &[Frame], | |
(skipped_before, skipped_after) | ||
} | ||
|
||
static MARK_START: fn(&mut FnMut()) = mark_start; | ||
|
||
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. | ||
/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1` | ||
#[inline(never)] | ||
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T | ||
where F: FnOnce() -> T, F: Send, T: Send | ||
{ | ||
f() | ||
fn mark_start(f: &mut FnMut()) { | ||
f(); | ||
unsafe { | ||
asm!("" ::: "memory" : "volatile"); // A dummy statement to prevent tail call optimization | ||
} | ||
} | ||
|
||
/// Convenience wrapper for `mark_start` | ||
#[unstable(feature = "rt", reason = "this is only exported for use in libtest", issue = "0")] | ||
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. Could this 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. Those are private usages in |
||
pub fn begin_short_backtrace<F: FnOnce() -> R, R>(f: F) -> R { | ||
let mut f = Some(f); | ||
let mut r = None; | ||
mark_start(&mut || { | ||
let f = f.take().unwrap(); | ||
r = Some(f()); | ||
}); | ||
r.unwrap() | ||
} | ||
|
||
/// Controls how the backtrace should be formated. | ||
|
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.
This may not compile on platforms like asm.js, so I wonder if we could take a perhaps different route to implement this? Could this call a
#[inline(never)]
function which doesn't throw using thenotail
attribute on the call? I think that'd do the same thing, right?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.
f
may throw here, so we cannot usenotail
. We need something that is opaque to LLVM. I suggest we just disable thisasm!
expressions on platforms which do not support it.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.
Ah yes indeed that's why we can't notail the call to
f
, but I"m thinking something like: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.
LLVM could still see that
foo
has no side effect, and just remove the call.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.
Ah indeed, in that case could something more portable than
asm!
be used, like volatile reads or something like that?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.
I don't think volatile operations will work as they could be reordered to happen before the call to
f
, iff
contains no volatile operations itself.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.
Does LLVM accept empty inline assembly for asm.js?
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.
AFAIK no we disable inline assembly completely on asm.js. Does the reordering actually happen?
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.
I was asking about LLVM not rustc though. I do not know if the reordering could happen given LLVM's current optimizations.
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.
At least in the tests I was running it wasn't reordering, but I'm not sure if that's a guarantee? I figure we could at least try it as this'll need to be upgraded for emscripten anyway.