Skip to content
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

implement From<Frame> for BacktraceFrame #420

Merged
merged 4 commits into from
Apr 26, 2021

Conversation

glommer
Copy link
Contributor

@glommer glommer commented Apr 21, 2021

There are situations where we can only capture raw Frame (example:
capturing from a signal handler), but it could still be that we can
process them later and are not fully nostd in the environment.

With a conversion from Frame to BacktraceFrame, this is trivial. But
without it, we can't really use the pretty printers as they are reliant
on BacktraceFrame, not Frame.

Fixes: #419

There are situations where we can only capture raw `Frame` (example:
capturing from a signal handler), but it could still be that we can
process them later and are not fully nostd in the environment.

With a conversion from Frame to BacktraceFrame, this is trivial. But
without it, we can't really use the pretty printers as they are reliant
on BacktraceFrame, not Frame.

Fixes: rust-lang#419
@alexcrichton
Copy link
Member

Thanks! Can you add some tests for this as well?

@glommer
Copy link
Contributor Author

glommer commented Apr 21, 2021

I can, but I noticed that there aren't any tests in-file.
What kind of tests exactly are you looking for here?

@alexcrichton
Copy link
Member

Mostly just something that exercises this code. For example creating a list from a call to backtrace::trace and then after the trace is finished the frames are inspected.

@glommer
Copy link
Contributor Author

glommer commented Apr 23, 2021

test added

src/capture.rs Outdated

let mut frames = 0;
unsafe {
crate::trace_unsynchronized(|frame| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this use trace instead of trace_unsynchronized? Additionally can this use the BacktraceFrame after the closure to ensure that it's not accidentally holding on to any ephemeral pointeres?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we can use trace. I ended up using the unsynchronized version because that is what I was using in my code, no problem.

By using the backtrace frame, maybe I can return a vector and do the asserts by zipping both iterators. Would that be enough for you ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your comments. I also noticed that the test would fail in --release mode, and indeed skipping a frame is fragile as inlining can change it.

I used a better method that now succeeds with release and debug.

A new version is force-pushed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever testing is fine by me, I mainly just want to confirm that if the BacktraceFrame leaks out of the closure then it's still safe to use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks! (sorry our last two comments sort of collided)

I think the miri tests are failing but otherwise this looks good to go once tests are passing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, just saw that. I bet it is a similar issue with --release and --debug. I will try it locally and get back to you

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. The issue with miri is different: every backtrace generated has completely different addresses!
Fortunately they resolve to the same thing, so I am testing with that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my god, lol...

At least your code coverage is pretty good!!

The test that fails now is about features disabled. If I understand your code correctly, that's because resolving symbols need features to run. I can remove the last assert. It won't be doing that much in that case, but it is better than disabling the whole test in the absence of features. At least the conversion path is stressed.

Glauber Costa added 2 commits April 23, 2021 15:03
Every backtrace that miri generates - conversion or no conversion, has
totally different addresses. They all resolve to the same thing, though,
so test with that.
`cargo test --no-default-features --features std` fails because
frames are not resolved to symbols in that case. We'll just remove the
assert, rather than disabling the whole test on that case. At least the
code paths are stressed.
@alexcrichton
Copy link
Member

Looks good to me, thanks!

@alexcrichton alexcrichton merged commit 2b4727b into rust-lang:master Apr 26, 2021
@glommer glommer deleted the frame-conv branch September 21, 2021 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

creating a BacktraceFrame from Frame
2 participants