-
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
Tracking issue for unwind allowed/abort #58760
Comments
I've nominated this for the language team because I think we may want to consider stabilizing this "immediately." These attributes have existed for a long time and I think we're fairly confident we want something like this. |
Note that this is effectively saying that unwinding through FFI will no longer be undefined behavior in some cases; after all, there would be no point in allowing functions to be marked The question is, which cases? My understanding of the current implementation is that Rust-triggered unwinding behaves correctly when unwinding across C code, or across C++ code compiled with exceptions disabled, but may have issues when unwinding across C++ code that does use exceptions. That is, on platforms that support unwinding at all; WebAssembly doesn't support it unless you pass a flag to have LLVM manually emulate it, but that's just WebAssembly being broken as usual. :p I have no objection to stabilizing this subset of functionality "immediately", so 👍 on this in general. However, I’d also like to know how hard it would be to support full interoperability between Rust and C++ unwinding – that is, allowing Rust panics to unwind across C++ code, and allowing C++ exceptions to unwind across Rust code. @alexcrichton, you seem to be the author of most of the unwinding code; can you comment on how difficult this seems from your perspective, or what the biggest obstacle might be? One issue I know of is on Windows, where instead of using a separate personality function, Rust borrows the C++ one from msvcrt. From libpanic_unwind/seh.rs: //! 1. The `panic` function calls the standard Windows function
//! `_CxxThrowException` to throw a C++-like exception, triggering the
//! unwinding process.
//! 2. All landing pads generated by the compiler use the personality function
//! `__CxxFrameHandler3`, a function in the CRT, and the unwinding code in
//! Windows will use this personality function to execute all cleanup code on
//! the stack.
[..]
//! * Rust has no custom personality function, it is instead *always*
//! `__CxxFrameHandler3`. Additionally, no extra filtering is performed, so we
//! end up catching any C++ exceptions that happen to look like the kind we're
//! throwing. Note that throwing an exception into Rust is undefined behavior
//! anyway, so this should be fine. One option would be to use a custom personality function instead of Another option is to just continue treating Rust panics like C++ exceptions and fix any incompatibilities. Looking into the implementation more… With regard to "end up catching any C++ exceptions that happen to look like the kind we're throwing", I believe the relevant comparison is this one, which treat two void foo() {
uint64_t a[2] = {0, 1};
throw a;
} Well, If this is fixed:
|
Mention `unwind(aborts)` in diagnostics for `#[unwind]` Simplify input validation for `#[unwind]`, add tests cc rust-lang#58760 r? @Mark-Simulacrum
Mention `unwind(aborts)` in diagnostics for `#[unwind]` Simplify input validation for `#[unwind]`, add tests cc rust-lang#58760 r? @Mark-Simulacrum
…wind, r=Centril Add tracking issue for the unwind attribute cc rust-lang#58760
…wind, r=Centril Add tracking issue for the unwind attribute cc rust-lang#58760
From a technical perspective this is pretty feasible, but from a stabilization perspective is historically something we've never wanted to provide. We want the technical freedom to tweak unwinding as we see fit, which means it's not guaranteed to match what C++ does across every single platform. |
👍 I have an implementation of very fast local stack unwinding (which we use in our internal LD_PRELOAD-based memory profiler) which uses a shadow stack and trampolines to effectively cache previously unwound stack frames, and I need to clear all of the previously set trampolines when an exception gets thrown or all hell breaks loose. This needs the ability to be able to unwind through an FFI boundary. Since the default behavior was switched to abort-by-default I had to switch to nightly to get the previous behavior; it'd be nice to get this stable again. |
I am denominating this in favor of #58794. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Mention `unwind(aborts)` in diagnostics for `#[unwind]` Simplify input validation for `#[unwind]`, add tests cc rust-lang#58760 r? @Mark-Simulacrum
Mention `unwind(aborts)` in diagnostics for `#[unwind]` Simplify input validation for `#[unwind]`, add tests cc rust-lang#58760 r? @Mark-Simulacrum
Mention `unwind(aborts)` in diagnostics for `#[unwind]` Simplify input validation for `#[unwind]`, add tests cc rust-lang#58760 r? @Mark-Simulacrum
IMO the only case in which we can guarantee this to work properly is if the code on the other side of the FFI is Rust compiled with the exact same toolchain.
I'd prefer if doing that required Currently we assume that the code at the other side of |
Somehow I didn't actually know about this issue despite authoring a closely related RFC (rust-lang/rfcs#2699). Is there an actual RFC for |
What are the best ways for interested outsiders to help move this along? The lack of stabilization here is currently making us choose between UB and using nightly for Lucet, so I'm definitely willing to get my hands dirty to help. |
@joshtriplett just made a proposal for specification here: #63909 (comment) So I think the discussion in that PR is the place to go if you want to either monitor progress on this or add to the discussion. (Though I don't know that "adding to the discussion" would speed things up.) |
I think this issue should be closed now that the FFI-unwind project group exists and is working on an RFC to replace these attributes. @koute ^ The above links will be useful to you if you are still working on the project you described and have not already heard about the project group! |
The attributes have been removed, closing. |
See #52652 for the original discussion. There's also some additional discussion here: #48251.
The default was changed to abort-by-default in extern functions in this PR.
This is tracking the stabilization of the
#[unwind(allowed)]
(and#[unwind(abort)]
) attributes.The text was updated successfully, but these errors were encountered: