Skip to content

Commit e57a0cd

Browse files
committed
new guarantee regarding drops before abort; document what happens when foreign unwind causes process termination
1 parent 6ffd283 commit e57a0cd

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

src/behavior-considered-undefined.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Please read the [Rustonomicon] before writing unsafe code.
7575
* Violating assumptions of the Rust runtime. This is only possible using
7676
mechanisms outside Rust. Most assumptions of the Rust runtime are currently
7777
not explicitly documented.
78-
* For assumptions specifically related to unwinding, see [unwinding-ub].
78+
* For assumptions specifically related to unwinding, see [unwinding-ffi].
7979
* The runtime assumes that a Rust stack frame is not deallocated without
8080
executing destructors for local variables owned by the stack frame. This assumption
8181
can be violated by C functions like `longjmp`.
@@ -196,5 +196,5 @@ reading uninitialized memory is permitted are inside `union`s and in "padding"
196196
[project-field]: expressions/field-expr.md
197197
[project-tuple]: expressions/tuple-expr.md#tuple-indexing-expressions
198198
[project-slice]: expressions/array-expr.md#array-and-slice-indexing-expressions
199-
[unwinding-ub]: panic.md#unwinding-ub
199+
[unwinding-ffi]: panic.md#unwinding-ffi
200200
[const-promoted]: destructors.md#constant-promotion

src/crates-and-source-files.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ use foo::bar as main;
103103
<!-- If the previous section needs updating (from "must take no arguments"
104104
onwards, also update it in the testing.md file -->
105105

106+
### Uncaught foreign unwinding
107+
108+
When a "foreign" unwind (e.g. an exception thrown from C++ code, or a `panic!`
109+
in Rust code compiled or linked with a different runtime) is not caught before
110+
reaching the `main` function, the process will be safely terminated. This may
111+
take the form of an abort, in which case it is not guaranteed that any `Drop`
112+
calls will be executed, and the error output may be less informative than if the
113+
runtime had been terminated by a "native" Rust `panic`.
114+
115+
For more information, see the [panic documentation][panic-docs].
116+
106117
### The `no_main` attribute
107118

108119
The *`no_main` [attribute]* may be applied at the crate level to disable
@@ -142,6 +153,7 @@ or `_` (U+005F) characters.
142153
[function]: items/functions.md
143154
[module]: items/modules.md
144155
[module path]: paths.md
156+
[panic-docs]: panic.md#unwinding-ffi
145157
[shebang]: input-format.md#shebang-removal
146158
[trait or lifetime bounds]: trait-bounds.md
147159
[where clauses]: items/generics.md#where-clauses

src/items/functions.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,20 @@ from the "Native unwind" column in the table.
244244
| panic runtime | ABI | `panic`-unwind | Native unwind (unforced) |
245245
| -------------- | ------------ | ------------------------------------- | ----------------------- |
246246
| `panic=unwind` | unwinding | unwind | unwind |
247-
| `panic=unwind` | non-unwinding | abort | [undefined behavior] |
247+
| `panic=unwind` | non-unwinding | abort[^1] | [undefined behavior] |
248248
| `panic=abort` | unwinding | `panic!` aborts (no unwinding occurs) | abort |
249249
| `panic=abort` | non-unwinding | `panic!` aborts (no unwinding occurs) | [undefined behavior] |
250250

251+
[^1]: In this case, either no destructors (`Drop` calls) will run, or all
252+
destructors up until the `extern "C"` boundary (or other such "no unwind"
253+
boundary) will run.
254+
255+
For other considerations and limitations regarding unwinding across FFI
256+
boundaries, see the [relevant section in the Panic documentation][panic-ffi].
257+
251258
[forced-unwinding]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html#forced-unwinding
252259
[panic-modes]: ../panic.md#panic-runtimes
260+
[panic-ffi]: ../panic.md#unwind-ffi
253261
[undefined behavior]: ../behavior-considered-undefined.md
254262

255263
## Const functions

src/panic.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@ just as if they had gone out of scope normally.
4040
> continue running).
4141
4242
### Unwinding across FFI boundaries
43-
[unwinding-ub]: #unwinding-across-ffi-boundaries
43+
[unwinding-ffi]: #unwinding-across-ffi-boundaries
4444

45-
It is possible to unwind across FFI boundaries; this creates unique
46-
opportunities for undefined behavior, especially when multiple language
47-
runtimes are involved.
45+
It is possible to unwind across FFI boundaries using an [appropriate ABI
46+
declaration][unwind-abi]. While useful in certain cases, this creates unique
47+
opportunities for undefined behavior, especially when multiple language runtimes
48+
are involved.
4849

49-
Unwinding with the wrong [ABI][abi] is undefined behavior:
50+
Unwinding with the wrong ABI is undefined behavior:
5051

5152
* Causing an unwind into Rust code from a foreign function that was called via a
5253
function declaration or pointer declared with a non-unwinding ABI, such as `"C"`,
@@ -92,10 +93,10 @@ impossible, which can result in both code-size and runtime speed improvements.
9293

9394
See also the [`panic_handler` attribute](runtime.md#the-panic_handler-attribute) which can be used to change the behavior of panics.
9495

95-
[abi]: abi.md
9696
[array indexing]: expressions/array-expr.md#array-and-slice-indexing-expressions
9797
[destructors]: destructors.md
9898
[fn-catch-unwind]: ../std/panic/fn.catch_unwind.html
9999
[macro-panic]: ../std/macro.panic.html
100100
[runtime]: runtime.md
101101
[thread-spawn]: ../std/thread/fn.spawn.html
102+
[unwind-abi]: items/functions.md#unwinding

0 commit comments

Comments
 (0)