Skip to content

Allow foreign exceptions to unwind through Rust code and Rust panics to unwind through FFI - #65646

Merged
bors merged 7 commits into
rust-lang:masterfrom
Amanieu:foreign-exceptions
Nov 3, 2019
Merged

bors merged 7 commits into
rust-lang:masterfrom
Amanieu:foreign-exceptions

Conversation

@Amanieu

@Amanieu Amanieu commented Oct 21, 2019 •

Copy link
Copy Markdown
Member

This PR fixes interactions between Rust panics and foreign (mainly C++) exceptions.

C++ exceptions (and other FFI exceptions) can now safely unwind through Rust code:

  • The FFI function causing the unwind must be marked with #[unwind(allowed)]. If this is not the case then LLVM may optimize landing pads away with the assumption that they are unreachable.
  • Drop code will be executed as the exception unwinds through the stack, as with a Rust panic.
  • catch_unwind will not catch the exception, instead the exception will silently continue unwinding past it.

Rust panics can now safely unwind through C++ code:

  • C++ destructors will be called as the stack unwinds.
  • The Rust panic can only be caught with catch (...), after which it can be either rethrown or discarded.
  • C++ cannot name the type of the Rust exception object used for unwinding, which means that it can't be caught explicitly or have its contents inspected.

Tests have been added to ensure all of the above works correctly.

Some notes about non-C++ exceptions:

  • pthread_cancel and pthread_exit use unwinding on glibc. This has the same behavior as a C++ exception: destructors are run but it cannot be caught by catch_unwind.
  • longjmp on Windows is implemented using unwinding. Destructors are run on MSVC, but not on MinGW. In both cases the unwind cannot be caught by catch_unwind.
  • As with C++ exceptions, you need to mark the relevant FFI functions with #[unwind(allowed)], otherwise LLVM will optimize out the destructors since they seem unreachable.

I haven't updated any of the documentation, so officially unwinding through FFI is still UB. However this is a step towards making it well-defined.

Fixes #65441

cc @gnzlbg
r? @alexcrichton

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team T-libs-api [DEPRECATED; DO NOT USE]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

catch_unwind incorrectly tries to stop ForceUnwinds