-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Panics in destructors can cause the return value to be leaked #47949
Comments
Heh, this even happens on Rust 1.0 |
Rust 1.0 is far worse than this - it leaks everything when a destructor panics. |
@arielb1, could you explain why this is tagged as a soundness bug? The language makes no guarantee that destructors will ever be invoked. |
ping @rust-lang/compiler this should be triagged, even if it is not a soundness bug, unwinding working properly is something that a lot of code relies on. |
So, to be clear, it's not that we leak all destructors when panic in drop occurs. For example, this function drops both fn foo() {
let n = NoisyDrop::new();
let p = PanickyDrop;
} The specific scenario here is that:
I don't think it's quite right to say that "we make no guarantee that destructors will ever be invoked". We don't guarantee that all destructors are always invoked, but we do guarantee some things: for example, that if you have a local variable whose scope includes a call, it will be dropped when the call panics (here, let n = ...;
foo(); So the question is what we should guarantee in this particular scenario. Perhaps the answer is that we should just be very clear to document the current behavior, given how long it has existed. |
Adding T-lang -- I think that documenting the expected order would be a good first step. |
We discussed in the @rust-lang/lang meeting. Everyone agreed this behavior is wrong; the returned value ought to be dropped, presumably after all other variables in the frame have been dropped. Basically it should be equivalent to having stored the value into an outer let. However, as a good first step, it seems like we should begin by verifying the behavior with a more thorough set of test cases. For example, I found (playground) that the problem applies not only to returns but to any store: fn foo() -> NoisyDrop {
let n = NoisyDrop::new(1);
let x = {
let p = PanickyDrop;
NoisyDrop::new(2) // <-- dtor for this never runs
};
panic!()
} Ideally what we would do is this:
We thought perhaps @matthewjasper might be interested in tackling this, in particular =) |
I'm leaving nominated so we follow up next meeting and discuss priority -- how serious do we think it is to fix this. Obviously, this is a long-standing behavior. |
Oh, there's an issue for this.
This should be done for evaluation order as well.
The bug is in MIR construction. I don't think it's that hard to fix (except possibly for the return place).
=) |
Oh? |
…komatsakis Expand dynamic drop tests for cases in rust-lang#47949 Adds test cases for rust-lang#47949
Rollup of 8 pull requests Successful merges: - #60729 (Expand dynamic drop tests for cases in #47949) - #61263 (Don't generate div inside header (h4/h3/h...) elements) - #61364 (Stabilize reverse_bits feature) - #61375 (Make "panic did not include expected string" message consistent) - #61387 (Remove ty::BrFresh and RegionConstraintCollector::new_bound) - #61389 (Remove GlobalArenas and use Arena instead) - #61391 (Doc comment fixes for `rustc::mir::interpret::InterpretCx`) - #61403 (Remove unnecessary `-Z continue-parse-after-error` from tests) Failed merges: r? @ghost
…ution-via-revert-of-pr-78373, r=matthewjasper Revert 78373 ("dont leak return value after panic in drop") Short term resolution for issue rust-lang#80949. Reopen rust-lang#47949 after this lands. (We plan to fine-tune PR rust-lang#78373 to not run into this problem.)
Reopening due to PR #81257 |
…ution-via-revert-of-pr-78373, r=matthewjasper Revert 78373 ("dont leak return value after panic in drop") Short term resolution for issue rust-lang#80949. Reopen rust-lang#47949 after this lands. (We plan to fine-tune PR rust-lang#78373 to not run into this problem.)
This has a conceptionally clear fix by changing MIR building which does not cause any issues, expect a single borrowck regression in #80949. It has also been encountered in the wild at least once in #47949 (comment). Going to bump this to I personally would be in favor of merging #78373 again, even if it still breaks |
I agree we should fix this. I don't recall the solution in detail nor the issue though. @lcnr it seems to me that FCP is appropriate -- this is likely a @rust-lang/types FCP with @rust-lang/lang cc'd? |
An FCP to merge #78373 again, accepting the regressions caused by it, assuming no additional major crates started to depend on the current behavior? hmm, not totally sure which team is the most responsible here. I feel like it may be types > @rust-lang/compiler > lang as it feels more like an implementation detail/bug than an actual lang design question🤔 Yes, that seems good to me. Will put this on my list of things I'd like to do, though I would love for someone else to summarize this for an FCP proposal, as I may not get to it in the near future. |
@nikomatsakis this is something I explored with the panic reachability logic in redpen. I can detect that a panic might happen in a |
@lcnr I agree with that ordering.
…On Thu, May 23, 2024, at 3:40 PM, lcnr wrote:
An FCP to merge #78373 <#78373> again, accepting the regressions caused by it, assuming no additional major crates started to depend on the current behavior?
hmm, not totally sure which team is the most responsible here. I feel like it may be types > @rust-lang/compiler <https://github.com/orgs/rust-lang/teams/compiler> > lang as it feels more like an implementation detail/bug than an actual lang design question🤔
Yes, that seems good to me. Will put this on my list of things I'd like to do, though I would love for someone else to summarize this for an FCP proposal, as I may not get to it in the near future.
—
Reply to this email directly, view it on GitHub <#47949 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AABF4ZT5HXOWTJMHOBNMZ23ZDZA2VAVCNFSM4EOZTMO2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMJSG44DSNJTHA3Q>.
You are receiving this because you modified the open/close state.Message ID: ***@***.***>
|
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
Fix leaks from panics in destructors Resurrects rust-lang#78373. This avoids the problem with rust-lang#80949 by not unscheduling drops of function arguments until after the call (so they still get a drop terminator on the function unwind path). Closes rust-lang#47949 r? `@lcnr`
STR
Expected Result
"creating a NoisyDrop" and "dropping a NoisyDrop" should appear the same number of times
Actual Result
The destructor is ignored.
The text was updated successfully, but these errors were encountered: