Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upTracking issue for unwind allowed/abort #58760
Comments
Mark-Simulacrum
added
I-nominated
T-lang
C-tracking-issue
labels
Feb 26, 2019
This comment has been minimized.
This comment has been minimized.
|
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. |
Mark-Simulacrum
referenced this issue
Feb 26, 2019
Merged
Add tracking issue for the unwind attribute #58761
petrochenkov
referenced this issue
Feb 26, 2019
Merged
Mention `unwind(aborts)` in diagnostics for `#[unwind]` #58762
This comment has been minimized.
This comment has been minimized.
|
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 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:
|
Centril
added a commit
to Centril/rust
that referenced
this issue
Feb 27, 2019
Centril
added a commit
to Centril/rust
that referenced
this issue
Feb 27, 2019
Centril
added a commit
to Centril/rust
that referenced
this issue
Feb 27, 2019
Centril
added a commit
to Centril/rust
that referenced
this issue
Feb 27, 2019
This comment has been minimized.
This comment has been minimized.
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. |
This comment has been minimized.
This comment has been minimized.
|
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. |
Mark-Simulacrum
referenced this issue
Feb 28, 2019
Open
Default behavior of unwinding in FFI functions #58794
This comment has been minimized.
This comment has been minimized.
|
I am denominating this in favor of #58794. |
Mark-Simulacrum
removed
the
I-nominated
label
Feb 28, 2019
This comment was marked as resolved.
This comment was marked as resolved.
That's infinite recursion there... Did you mean a different issue number? |
This comment was marked as resolved.
This comment was marked as resolved.
|
Yes, #58794. |
Centril
added a commit
to Centril/rust
that referenced
this issue
Mar 9, 2019
Centril
added a commit
to Centril/rust
that referenced
this issue
Mar 9, 2019
Centril
added a commit
to Centril/rust
that referenced
this issue
Mar 9, 2019
This comment has been minimized.
This comment has been minimized.
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 |
Mark-Simulacrum commentedFeb 26, 2019
•
edited
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.