- Feature Name:
project-unwind-FFI
- Start Date: 2019-10-27
- RFC PR: rust-lang/rfcs#2797
- Rust Issue: N/A
Summary
- To create a “project group” with the purpose of designing subsequent RFCs to
extend the language to support unwinding that crosses FFI boundaries
- The “project group” term is newly introduced: it is a specific type of working group whose goal is to flesh out a particular proposal or complete a project.
- This project group plans to recommend specifications of how “C unwind” will work on major platforms.
- The primary goal is to enable Rust panics to propagate safely across
foreign frames.
- A future goal may be to enable foreign exceptions to propagate across Rust frames.
- We do not plan to allow catching or throwing foreign exceptions from Rust code
Motivation
Unwinding through Rust’s extern "C"
ABI is Undefined Behavior. There is an
existing plan to make the behavior of Rust’s panic
well-defined by causing Rust functions defined with extern "C"
to abort the
application whenever an uncaught panic
would otherwise escape into the
caller. Unfortunately, previous attempts to stabilize this behavior have caused
existing, working projects to break.
The problem here is not that the existing projects break per se: they are relying on Undefined Behavior, so breakage is to be expected as a possibility. The problem is that there is no alternative available to them that would allow them to keep working (even if they are continuing to rely on behavior that is not yet fully specified).
Previous attempts to provide a well-defined mechanism for unwinding across FFI boundaries have failed to reach consensus. Notably, two proposed RFCs generated over 400 comments between them before ultimately being closed:
GitHub comment threads become difficult to follow for discussions this lengthy, and the disagreements in these threads have felt less productive than we believe they could be if more structure were provided.
We would also like to demonstrate the Rust lang team’s commitment to providing such a mechanism without needing to agree in advance on what language changes will be stabilized in order to do so.
Prototyping ‘shepherded’ project groups
With this RFC, we formally announce the formation of a project-specific, shepherded “project group” to adopt responsibility for driving progress on specifying unwinding behavior at FFI boundaries.
What is a “project group”?
The “project group” term has not previously been used: it is intended to formalize a concept that has existed informally for some time, under a number of names (including “working group”).
A “project group” is a group of people working on a particular project at the behest of an official Rust team. Project groups must have:
- A charter defining the project’s scope
- A liaison with an official Rust team (who may or may not also be a shepherd)
- A small number of shepherds, who are responsible for summarizing conversations and keeping the lang team abreast of interesting developments.
- A GitHub repository hosted under the
rust-lang
organization containing the charter and instructions for how community members can monitor the group’s progress and/or participate.
This blog post explains in detail the role of the shepherds.
Project group roadmap and RFCs
The first step of the project group is to define a roadmap indicating the planned sequence in which it will design and propose particular behaviors and features. Once the project group feels it has completed work on some item in the roadmap, that item will be submitted as an RFC or FCP for review by the lang team and the community at large.
Stabilizing unspecified “TBD” behavior
We would like to be able to provide features in stable Rust where some of the details are only partially specified. For example, we might add a new ABI “C unwind” that can be used from stable Rust, while explicitly leaving the behavior when a foreign exception unwinds across such a boundary unspecified. In such cases, we would attempt to provide some bounds on what might happen – for example, we might state that a Rust panic propagating across a “C unwind” boundary must be preserved and handled as normal.
In some cases, we intend to mark some of this unspecified behavior as “To Be Determined” (TBD). This classification is meant to convey that the behavior is behavior we intend to specify as part of this group, although we have not done so yet. This categorization is purely intental to the working group, however; such behavior would remain formally unspecified until an RFC or other binding decision is reached.
Details of the FFI-unwind project group
Initial shepherds:
Lang team liaisons:
Charter
The FFI-unwind project group has the following initial scope:
- to define the details of the “C unwind” ABI on major Tier 1 platforms
- in particular, to define with sufficient detail to enable the use cases described in the Motivation section of this RFC
Certain elements are considered out of scope, at least to start:
- We do not expect to add new mechanisms for interacting with or
throwing foreign exceptions.
- However, if we specify what happens when a foreign exception
passes into Rust code, then we must also specify how that
exception will interact with pre-existing mechanisms like
destructors and
catch_unwind
. We just don’t intend to create new mechanisms.
- However, if we specify what happens when a foreign exception
passes into Rust code, then we must also specify how that
exception will interact with pre-existing mechanisms like
destructors and
Constraints and considerations
In its work, the project-group should consider various constraints and considerations:
- The possibility that C++ may adopt new unwinding mechanisms in the future.
- The possibility that Rust may alter its unwinding mechanism in the future – in particular, the project group must not propose a design that would constrain Rust’s unwinding implementation on any target.
Participation in the project group
Like any Rust group, the FFI-unwind project group intends to operate in a public and open fashion and welcomes participation. Visit the repository for more details.
Drawbacks
- The adoption of project groups for major language design efforts is a change in the status quo. We believe that this change will be an improvement over the current RFC-centric process, but we should be wary of unintended consequences of from such a change.
- Stabilization of “TBD” features may be surprising or confusing to users, and it will encourage reliance on (some) unspecified behavior.
Prior art
Although the term “project group” is new, some existing efforts, such as the Unsafe Code Guidelines effort and the work around defining const evaluation, were organized in a similar fashion.
In addition to the blog post Niko Matsakis about shepherding, James Munns wrote a more formal shepherding proposal.
The governance WG and lang-team meta working group were both formed at least in part to improve the process for large-scale design efforts. One existing proposal is for “staged RFCs”; this may be considered a precursor to the current “shepherded project group” proposal.
Unresolved questions and Future possibilities
Since this RFC merely formalizes the creation of the project group, it intentionally leaves all technical details within the project’s scope unresolved.
Future possibilities
The project group will start with a fairly limited scope, but if the initial effort to design and stabilize a safe cross-language unwinding feature on a limited set of platforms goes well, there are many related areas of potential exploration. Three noteworthy examples are:
- Catching foreign unwinding (e.g. Rust catching C++ exceptions, or C++
catching Rust
panic
s) - Defining coercions among
fn
s using ABIs with differentunwind
behavior - Monitoring progress, or even participating in discussion about, the ISO C and C++ proposal for cross-language error handling