-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Rework handling of recursive panics #110975
Conversation
(rustbot has picked a reviewer for you, use r? to override) |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
This comment has been minimized.
This comment has been minimized.
The Miri subtree was changed cc @rust-lang/miri |
This comment has been minimized.
This comment has been minimized.
I don't know why the test is failing. It claims that |
The change in panic runtime looks correct to me. |
☔ The latest upstream changes (presumably #111036) made this pull request unmergeable. Please resolve the merge conflicts. |
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.
👍 on the Miri changes
8244990
to
02a0faa
Compare
☔ The latest upstream changes (presumably #111454) made this pull request unmergeable. Please resolve the merge conflicts. |
@bors r+ rollup |
Rework handling of recursive panics This PR makes 2 changes to how recursive panics works (a panic while handling a panic). 1. The panic count is no longer used to determine whether to force an immediate abort. This allows code like the following to work without aborting the process immediately: ```rust struct Double; impl Drop for Double { fn drop(&mut self) { // 2 panics are active at once, but this is fine since it is caught. std::panic::catch_unwind(|| panic!("twice")); } } let _d = Double; panic!("once"); ``` Rustc already generates appropriate code so that any exceptions escaping out of a `Drop` called in the unwind path will immediately abort the process. 2. Any panics while the panic hook is executing will force an immediate abort. This is necessary to avoid potential deadlocks like rust-lang#110771 where a panic happens while holding the backtrace lock. We don't even try to print the panic message in this case since the panic may have been caused by `Display` impls. Fixes rust-lang#110771
@bors rollup=iffy |
Should be fixed now. @rustbot ready |
@bors r=joshtriplett |
☀️ Test successful - checks-actions |
Finished benchmarking commit (f91b634): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 645.972s -> 646.05s (0.01%) |
This PR seems to have introduced a regression, namely this playground example mentioned here no longer shows any stacktraces as it used to do when the comment was made back in 2022. EDIT2: ok, the reason it doesn't show is because now As this seem to be by design( Either way, the double panic is caused by the rust/library/std/src/panicking.rs Lines 777 to 784 in 03994e4
and thus doesn't even get to execute a potential user panic hook, or the default panic hook. ...though it's by design: |
Printing just the location should be fine since this doesn't execute any user-controlled code. Feel free to submit a PR for this. |
EDIT4: I'm wrong here because we'd be using
some not relevant infoand I've stumbled upon that as I've tried to do something else:
(those are from chatgpt btw) EDIT: lookslike, in my particular example with alloc, I can use a static AtomicBool (not thread local tho) to guard the println! so it doesn't infinitely recurse the alloc.(EDIT2: Note that I'm rather noobish at this and I'm just trying to learn things as I go along, which is surprisingly way more fun than just reading the rust book(which I've failed to do many times over the years) |
Do you have a reliable source for that information? ChatGPT is just as likely to hallucinate some nonsense as it is to provide useful information.
I also fail to see how it is relevant; we are talking about panics during panic handling, not about allocation failures. The vast majority of panics is unrelated to allocation failure, including the examples shared here.
|
tl;dr:
You may be right, because an allocation(1024 bytes EDIT1: that's apparently happening due to a pub fn stdout() -> Stdout {
Stdout {
inner: STDOUT
.get_or_init(|| ReentrantMutex::new(RefCell::new(LineWriter::new(stdout_raw())))),
}
} I guess then println! doesn't otherwise alloc, and chatgpt hallucinated as you said.(happens way too often) Lines 34 to 40 in 1204400
Calls that panic_output() which does NOT alloc:rust/library/std/src/sys/unix/stdio.rs Lines 91 to 93 in 1204400
because StdErr::new() doesn't alloc: rust/library/std/src/sys/unix/stdio.rs Lines 59 to 61 in 1204400
or maybe it rust/library/std/src/sys/windows/stdio.rs Lines 400 to 402 in 1204400
rust/library/std/src/sys/windows/stdio.rs Lines 379 to 380 in 1204400
Side note: eprintln!() doesn't alloc that stderr() 1024 byte buffer, like println! does with the stdout() one. ie. As to why it is relevant, it's because we can't do new allocations there in panic handling code because:
|
Code that forks has to set rust/library/std/src/panicking.rs Lines 752 to 760 in b4ca582
So it's already a separate codepath and in the other codepaths, we are in principle free to use allocation (and existing code relies on that). But anyway, closed PRs are a bad place to discuss anything. If you think something needs to be improved or something is wrong with when we do or do not allocate, please file an issue. The problem of not having enough panic location information in some cases is tracked at #97181. If you want to learn why the current code makes sense, I suggest asking on Zulip. |
Thanks. I just want to add, that at line 755 there, rust/library/std/src/panicking.rs Lines 746 to 750 in b4ca582
this is why I was worried about allocating when printing the location there, but since Thanks for making the PR, I couldn't have done it in time, I don't have the environment set up for a git version of rust that I could test that all its test cases wouldn't break because of introducing the change. (and I will look into Zulip, thx) EDIT: Actually, looks like I'm wrong because line 394 there says it always returns the same rust/library/std/src/panicking.rs Lines 391 to 405 in b4ca582
this means it's a bug(in the context that i've framed it), right? EDIT2: kind of, if infinite panic nesting is encountered, then it's a bug, like this: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=ee739d9534ba3924e6113bfa79f60fbf but comment out the std::panic::always_abort(); line and it's not infinite recursion.
|
This PR makes 2 changes to how recursive panics works (a panic while handling a panic).
Rustc already generates appropriate code so that any exceptions escaping out of a
Drop
called in the unwind path will immediately abort the process.Display
impls.Fixes #110771