-
Notifications
You must be signed in to change notification settings - Fork 533
panic runtime and C-unwind documentation #1226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5f63e46
c8fc0e8
edd5b18
39de76c
6413901
70f8292
d08e406
a20802e
2525ab4
5bff1e3
7453efd
c3cc7fa
860691e
543bc27
4bb0248
386b2f3
c7a7961
20af0b1
da53531
8fd8208
0f3c015
63677c1
caa17fc
0b37538
eafe95d
5f21a1a
79cc53f
c38044d
20bd38f
f309b2f
2617cd5
d49c90c
6eaa1fa
a740002
f7cb25e
34e0b68
8f4dc2b
6e76b5c
7049886
003a8a4
cdd00de
ffc056c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -254,20 +254,43 @@ let fptr: extern "C" fn() -> i32 = new_i32; | |||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.extern.unwind] | ||||||||||||||||||||||||||||||||||||||||||||||
Functions with an ABI that differs from `"Rust"` do not support unwinding in the | ||||||||||||||||||||||||||||||||||||||||||||||
exact same way that Rust does. Therefore, unwinding past the end of functions | ||||||||||||||||||||||||||||||||||||||||||||||
with such ABIs causes the process to abort. | ||||||||||||||||||||||||||||||||||||||||||||||
### Unwinding | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
> **Note**: The LLVM backend of the `rustc` implementation | ||||||||||||||||||||||||||||||||||||||||||||||
aborts the process by executing an illegal instruction. | ||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.extern.unwind.intro] | ||||||||||||||||||||||||||||||||||||||||||||||
Most ABI strings come in two variants, one with an `-unwind` suffix and one without. The `Rust` ABI always permits unwinding, so there is no `Rust-unwind` ABI. The choice of ABI, together with the runtime [panic handler], determines the behavior when unwinding out of a function. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.extern.unwind.behavior] | ||||||||||||||||||||||||||||||||||||||||||||||
The table below indicates the behavior of an unwinding operation reaching each type of ABI boundary (function declaration or definition using the corresponding ABI string). Note that the Rust runtime is not affected by, and cannot have an effect on, any unwinding that occurs entirely within another language's runtime, that is, unwinds that are thrown and caught without reaching a Rust ABI boundary. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
For (*1), I am relying on rust-lang/rust#52652 (comment) . For (*2), an alternative would be to make the point at which the abort occurs for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know that the way aborts are implemented guarantees that on all platforms for point 2. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think that's part of rust-lang/rust#123231. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reminder to pull this suggestion out to a new PR if it's still correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the suggestion is covered by the verbiage below the table, I don't see or recall anything in rust-lang/rust#115285 that matches the proposal suggested above of making all entries in the furthest-right column well-defined, so I think that part of the suggestion is simply incorrect. @daira please let me know if you disagree after reviewing that issue, or if you meant to link to a different issue. |
||||||||||||||||||||||||||||||||||||||||||||||
The `panic`-unwind column refers to [panicking] via the `panic!` macro and similar standard library mechanisms, as well as to any other Rust operations that cause a panic, such as out-of-bounds array indexing or integer overflow. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
The "unwinding" ABI category refers to `"Rust"` (the implicit ABI of Rust functions not marked `extern`), `"C-unwind"`, and any other ABI with `-unwind` in its name. The "non-unwinding" ABI category refers to all other ABI strings, including `"C"` and `"stdcall"`. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
Native unwinding is defined per-target. On targets that support throwing and catching C++ exceptions, it refers to the mechanism used to implement this feature. Some platforms implement a form of unwinding referred to as ["forced unwinding"][forced-unwinding]; `longjmp` on Windows and `pthread_exit` in `glibc` are implemented this way. Forced unwinding is explicitly excluded from the "Native unwind" column in the table. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
| panic runtime | ABI | `panic`-unwind | Native unwind (unforced) | | ||||||||||||||||||||||||||||||||||||||||||||||
| -------------- | ------------ | ------------------------------------- | ----------------------- | | ||||||||||||||||||||||||||||||||||||||||||||||
| `panic=unwind` | unwinding | unwind | unwind | | ||||||||||||||||||||||||||||||||||||||||||||||
| `panic=unwind` | non-unwinding | abort (see notes below) | [undefined behavior] | | ||||||||||||||||||||||||||||||||||||||||||||||
| `panic=abort` | unwinding | `panic` aborts without unwinding | abort | | ||||||||||||||||||||||||||||||||||||||||||||||
| `panic=abort` | non-unwinding | `panic` aborts without unwinding | [undefined behavior] | | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.extern.abort] | ||||||||||||||||||||||||||||||||||||||||||||||
With `panic=unwind`, when a `panic` is turned into an abort by a non-unwinding ABI boundary, either no destructors (`Drop` calls) will run, or all destructors up until the ABI boundary will run. It is unspecified which of those two behaviors will happen. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
For other considerations and limitations regarding unwinding across FFI boundaries, see the [relevant section in the Panic documentation][panic-ffi]. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
[forced-unwinding]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html#forced-unwinding | ||||||||||||||||||||||||||||||||||||||||||||||
[panic handler]: ../panic.md#the-panic_handler-attribute | ||||||||||||||||||||||||||||||||||||||||||||||
[panic-ffi]: ../panic.md#unwinding-across-ffi-boundaries | ||||||||||||||||||||||||||||||||||||||||||||||
[panicking]: ../panic.md | ||||||||||||||||||||||||||||||||||||||||||||||
[undefined behavior]: ../behavior-considered-undefined.md | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
BatmanAoD marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.const] | ||||||||||||||||||||||||||||||||||||||||||||||
## Const functions | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.const.intro] | ||||||||||||||||||||||||||||||||||||||||||||||
Functions qualified with the `const` keyword are [const functions], as are | ||||||||||||||||||||||||||||||||||||||||||||||
[tuple struct] and [tuple variant] constructors. _Const functions_ can be | ||||||||||||||||||||||||||||||||||||||||||||||
called from within [const contexts]. | ||||||||||||||||||||||||||||||||||||||||||||||
Functions qualified with the `const` keyword are [const functions], as are [tuple struct] and [tuple variant] constructors. _Const functions_ can be called from within [const contexts]. | ||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||
r[items.fn.const.extern] | ||||||||||||||||||||||||||||||||||||||||||||||
Const functions may use the [`extern`] function qualifier. | ||||||||||||||||||||||||||||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.