Skip to content

Commit e89faee

Browse files
author
Kyle Strand
committed
Summarize a few years of discussion
1 parent fb230ed commit e89faee

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

rfcs/0000-c-unwind-abi.md

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ the Lucet and Wasmer projects.
3535
There are also existing Rust crates (notably, wrappers around the `libpng` and
3636
`libjpeg` C libraries) that `panic` across C frames. The safety of such
3737
unwinding relies on compatibility between Rust's unwinding mechanism and the
38-
native exception mechanisms in GCC, LLVM, and MSVC.
38+
native exception mechanisms in GCC, LLVM, and MSVC. Despite using a compatible
39+
unwinding mechanism, the current `rustc` implementation assumes that `extern
40+
"C"` functions cannot unwind, which permits LLVM to optimize with the
41+
assumption that such unwinding constitutes undefined behavior.
3942

4043
Additionally, there are libraries such as `rlua` that rely on `longjmp` across
4144
Rust frames; on Windows, `longjmp` is implemented via [forced
@@ -180,6 +183,7 @@ Rust [POFs][POF-definition]. If those Rust frames are not POFs, then invoking
180183
[inside-rust-forced]: https://blog.rust-lang.org/inside-rust/2020/02/27/ffi-unwind-design-meeting.html#forced-unwinding
181184

182185
## Changes to `extern "C"` behavior
186+
[extern-c-behavior]: #changes-to-extern-c-behavior
183187

184188
Prior to this RFC, any unwinding operation that crossed an `extern "C"`
185189
boundary, either from a `panic!` "escaping" from a Rust function defined with
@@ -394,9 +398,10 @@ the new `"C unwind"` ABI.
394398

395399
Currently, nightly Rust provides attributes, `#[unwind(allowed)]` and
396400
`#[unwind(abort)]`, that permit users to select a well-defined behavior when a
397-
`panic` reaches an `extern "C"` function boundary. Two previous RFCs,
398-
[#2699][rfc-2699] and [#2753][rfc-2753], attempted to stabilize these or
399-
similar attributes.
401+
`panic` reaches an `extern "C"` function boundary. Stabilization of these
402+
attributes has [a tracking issue][attributes-tracking-issue], but most
403+
of the discussion about whether this was the best approach took place in two
404+
RFC PR threads, [#2699][rfc-2699] and [#2753][rfc-2753].
400405

401406
The attribute approach was deemed insufficient for the following reasons:
402407

@@ -417,20 +422,33 @@ The attribute approach was deemed insufficient for the following reasons:
417422
string is always part of its type, so we are not introducing any new elements
418423
to the type system.
419424

425+
[attributes-tracking-issue]: https://github.com/rust-lang/rust/issues/58760
420426
[rfc-2699]: https://github.com/rust-lang/rfcs/pull/2699
421427
[rfc-2753]: https://github.com/rust-lang/rfcs/pull/2753
422428

423-
## Other discussions
424-
<!-- TODO other discussions:
425-
Tickets:
426-
* https://github.com/rust-lang/rust/issues/58794
427-
* https://github.com/rust-lang/rust/issues/52652
428-
* https://github.com/rust-lang/rust/issues/58760
429-
* https://github.com/rust-lang/rust/pull/55982
430-
431-
Discourse:
432-
https://internals.rust-lang.org/t/unwinding-through-ffi-after-rust-1-33/9521?u=batmanaod
433-
-->
429+
## Older discussions about unwinding through `extern "C"` boundaries
430+
431+
As mentioned [above][motivation], it is currently undefined behavior for
432+
`extern "C"` functions to unwind. As documented in [this
433+
issue][abort-unwind-issue], the lang team has long intended to make `panic!`
434+
cause the runtime to abort rather than unwind through an `extern "C"` boundary
435+
(which the current proposal [also specifies][extern-c-behavior]).
436+
437+
The abort-on-unwind behavior was [stabilized in 1.24][1.24-release] and
438+
[reverted in 1.24.1][1.24.1-release]; the team originally planned to [stabilize
439+
it again][1.33-stabilization] in 1.33, but ultimately [decided not
440+
to][1.33-discussion]. Community discussion [on discourse][discourse-thread] was
441+
largely concerned with the lack of any stable language feature to permit
442+
unwinding across FFI boundaries, and this contributed to the decision to block
443+
the re-stabilization of the abort-on-unwind behavior until such a feature could
444+
be introduced.
445+
446+
[abort-unwind-issue]: https://github.com/rust-lang/rust/issues/52652
447+
[1.24-release]: https://blog.rust-lang.org/2018/02/15/Rust-1.24.html#other-good-stuff
448+
[1.24.1-release]: https://blog.rust-lang.org/2018/03/01/Rust-1.24.1.html#do-not-abort-when-unwinding-through-ffi
449+
[1.33-stabilization]: https://github.com/rust-lang/rust/pull/55982
450+
[1.33-discussion]: https://github.com/rust-lang/rust/issues/58794
451+
[discourse-thread]: https://internals.rust-lang.org/t/unwinding-through-ffi-after-rust-1-33/9521?u=batmanaod
434452

435453
# Unresolved questions
436454
[unresolved-questions]: #unresolved-questions

0 commit comments

Comments
 (0)