-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Abort in panic_abort eh_personality #86801
Conversation
r? @dtolnay (rust-highfive has picked a reviewer for you, use r? to override) |
This ensures that it is impossible to unwind through rust code in case of -Cpanic=abort
This comment has been minimized.
This comment has been minimized.
fe73ded
to
f604467
Compare
😳 This is not code that I am interested in ramping up on. Maybe r? @cuviper? |
How is that possible? How does this affect what happens when C++ throws an exception and it bubbles into Rust via |
Say you have //- crate_a.rs
// rustflags: -Cpanic=unwind
extern "C-unwind" {
fn may_throw_foreign_exception();
}
pub fn wrapper() {
unsafe { may_throw_foreign_exception(); }
}
//- crate_b.rs
// rustflags: -Cpanic=abort
fn main() {
a::wrapper();
} If the call to |
Yes that is exactly the magic I am asking about. :) I know nothing at all about "personality functions", so could you explain what is happening here (or provide some links to documents that properly explain this stuff)? |
When using DWARF based unwinding (used on pretty much all systems except windows), the https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html may be helpful. |
Okay, so basically there's a "magic function pointer" that we can set for each stack frame that is called on all kinds of unwinding, and we can make that one abort if the function was compiled with But you said this is not used on Windows. So the original unwinding problem remains on Windows then? |
Correct. I will need to read into SEH (the unwinding system on windows) to see if there is a way to achieve something similar on windows. |
https://docs.microsoft.com/en-us/windows/win32/debug/frame-based-exception-handling:
(emphasis mine) Looks like SEH has an equivalent to the personality function for DWARF based unwinding. To get the same effect as for DWARF with this PR, it would be necessary to unconditionally use such a filter function though I think. This may be a small perf loss when unwinding. I think this would be acceptable as panicking should rarely happen anyway, so it isn't perf critical. |
My main concern about this strategy is indeed platform support, namely Windows support. As pointed out here this PR, as-is at least, does not support MSVC. I attempted oh-so-long-ago to use a custom personality on MSVC as well (similar to how Things may have change in LLVM over time, but supporting a custom personality in the same way that we support it today may require changes on LLVM's side of things otherwise that may not be trivial. |
Would this PR be fine to merge as is given that it is strictly an improvement for systems using DWARF based unwinding and doesn't hurt SEH based unwinding? Even if a completely different implementation strategy is found, this will simply function as a fail-safe on most systems in case of a bug in rust and otherwise not do any harm. |
I'm not the reviewer of this PR, but AFAIK the main motivation is to remove a blocker from stabilizing |
I think I know the solution. If the current crate is not a panic runtime, then if the current crate is panic=abort a local |
I think that could work yeah. You'd want to test to ensure that it doesn't interfere with C++'s usaage of I also think you can probably eschew |
That is why I suggested making the generated
If code is compiled with panic=unwind, an abort would not always be a correct implementation. If the final program is panic=unwind, it needs to forward to the real |
If the personality function is an unconditional abort, doesn't that prevent foreign functions from performing any cleanup? e.g. your Or is the idea to make this effectively the same as an uncaught-exception's |
The personality function only applies to rust functions. C++ functions will still be able to unwind. Only when the exception reaches a rust function will it abort per the RFC.
When a panic happens with panic=abort we don't run the cleanup for any crate compiled with panic=unwind either. It makes sense to me to extend this to foreign exceptions when they would unwind through rust code. |
Ah ok I think that can work then. It feels a little convoluted but so long as LLVM is doing name matching on personalities we seem kinda forced to do this. I think it would be good to confirm that the name matching still happens though and it would probably be good to consult with an MSVC expert before committing to this pattern, though. Naturally I think it would all want to be well tested to ensure it's behaving as we expect. I don't know enough about MSVC to say with certainty that it will behave exactly as described here. |
Do you want to be? I was chosen somewhat arbitrarily, but I feel you better understand these details already. |
☔ The latest upstream changes (presumably #90382) made this pull request unmergeable. Please resolve the merge conflicts. |
Discussed in T-compiler meeting on Zulip. |
I wanted to come back here and write down my thoughts on where this issue is. Although the discussion here started around Windows support, I wanted to confirm that my concerns are Windows specific. If we have some code that would need cleanups (e.g., variables with destructors) but is compiled with If it does then I agree the above solution will work. For Windows to be certain to catch the unwind at the point it enters Rust code it seems like we would need to either:
|
I believe this PR is mostly superseded by #92845. You need a valid personality function even with panic=abort. |
It partly is. #92845 doesn't implement logic to make the personality function abort when trying to unwind in case of |
That logic already exists since #86155. The MIR pass will generate an abort landing pad since it sees a potentially unwinding call (the |
That only happens for crates compiled with |
@bjorn3 checking the progress for this PR: anything specific you need to be reviewed since last comments (I'm trying to recap the current status). thanks :) |
This doesn't work for windows yet. In addition once #92845 lands, I will need to change this PR. |
ok thanks for the update. I'll flip the switch and set it waiting-on-author so it reflects the current status (in general terms). When this will be ready for another round of review, it can go back to waiting-on-review @rustbot author |
Marking this as blocked on #92845 |
Does #97235 completely supersede this change? |
I don't think so. I suspect but haven't confirmed that the current implementation of panic_abort will cause foreign exceptions to unwind past rust code despite the landingpads. The current personality function in panic_abort says that unwinding should just continue. Either aborting in the panic_abort eh personality (as this PR does) or reusing panic_unwind's eh personality would fix this. |
I don't believe this is necessary anymore given changes that happened since. |
Which other changes? Would be good to leave a reference. |
I don't quite recall... |
I believe this is mainly #92845. Now the same personality function is used with both |
This ensures that it is impossible to unwind through rust code when there is any
-Cpanic=abort
rust code, even onceextern "C-unwind"
is implemented and used in-Cpanic=unwind
code.See https://rust-lang.zulipchat.com/#narrow/stream/210922-project-ffi-unwind/topic/next.20steps/near/244594484
Blocked on #92845