Skip to content

Commit 82c3a9c

Browse files
committed
Add the concept of panic strategy
This is intended to clearly define two concepts, the runtime versus the strategy. Although there is significant overlap between them (they are chosen using the same CLI flag after all), I think it is helpful to define them as separate concepts.
1 parent f576209 commit 82c3a9c

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/linkage.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ we define what exactly is meant by "handling unwinding consistently".
286286

287287
r[link.unwinding.potential]
288288
A Rust artifact is called *potentially unwinding* if any of the following conditions is met:
289-
- The artifact is linked with [the `panic=unwind` runtime][panic-runtime].
290-
- The artifact contains a crate built with `-Cpanic=unwind` that makes a call
289+
- The artifact is linked with [the `unwind` runtime][panic-runtime].
290+
- The artifact contains a crate built with the `unwind` [panic strategy] that makes a call
291291
to a function using a `-unwind` ABI.
292292
- The artifact makes a `"Rust"` ABI call to code running in another Rust
293293
artifact that has a separate copy of the Rust runtime, and that other artifact is
@@ -298,15 +298,15 @@ A Rust artifact is called *potentially unwinding* if any of the following condit
298298
> unwind.
299299
300300
r[link.unwinding.prohibited]
301-
If a Rust artifact is potentially unwinding, then all its crates must be built with `-Cpanic=unwind`.
301+
If a Rust artifact is potentially unwinding, then all its crates must be built with the `unwind` [panic strategy].
302302

303303
> [!NOTE]
304-
> This restriction can only be violated when mixing code with different `-C panic` flags
304+
> This restriction can only be violated when mixing code with different [`-C panic`] flags
305305
> while also using a non-`rustc` linker. Most users to not have to be concerned about this.
306306
307307
> [!NOTE]
308308
> To guarantee that a library will be sound (and linkable with `rustc`)
309-
> regardless of the panic mode used at link-time, the [`ffi_unwind_calls` lint]
309+
> regardless of the panic runtime used at link-time, the [`ffi_unwind_calls` lint]
310310
> may be used. The lint flags any calls to `-unwind` foreign functions or
311311
> function pointers.
312312
@@ -315,3 +315,5 @@ If a Rust artifact is potentially unwinding, then all its crates must be built w
315315
[configuration option]: conditional-compilation.md
316316
[panic-runtime]: panic.md#panic-runtimes
317317
[procedural macros]: procedural-macros.md
318+
[panic strategy]: panic.md#panic-strategy
319+
[`-C panic`]: ../rustc/codegen-options/index.html#panic

src/panic.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,39 @@ There are also language features that provide a level of control over panic beha
1919
r[panic.runtime]
2020
## Panic runtimes
2121

22-
The actual behavior and implementation of `panic!` is controlled by the _panic runtime_.
22+
The actual behavior and implementation of a panic is controlled by the _panic runtime_. The panic runtime is a handler linked into the output which provides the necessary implementation for panicking.
2323

2424
> [!NOTE]
2525
> The Rust standard library provides two panic runtimes: `panic_unwind` (which unwinds the stack and is potentially recoverable) and `panic_abort` (which aborts the process and is non-recoverable). The default runtime depends on the target platform, but is generally `panic_unwind` on platforms with native support for C++ exceptions.
2626
27+
> [!NOTE]
28+
> The panic runtime can be chosen in `rustc` with the [`-C panic`] CLI flag when building any crate type except an rlib.
29+
2730
> [!NOTE]
2831
> When compiling code that is guaranteed to be linked to a non-recoverable panic runtime, the optimizer may assume that unwinding across Rust frames is impossible, which can result in both code-size and runtime speed improvements.
2932
3033
See also the [`panic_handler` attribute](runtime.md#the-panic_handler-attribute) which can be used to change the behavior of panics.
3134

35+
r[panic.strategy]
36+
## Panic strategy
37+
38+
r[panic.strategy.intro]
39+
The _panic strategy_ defines the kind of panic runtime that a crate is built to support.
40+
41+
> [!NOTE]
42+
> The panic strategy can be chosen in `rustc` with the [`-C panic`] CLI flag.
43+
44+
r[panic.strategy.mixed]
45+
When linking with the `unwind` runtime, all crates must be built with the `unwind` strategy.
46+
3247
r[panic.unwind]
3348
## Unwinding
3449

3550
r[panic.unwind.intro]
36-
Panicking may either be recoverable or non-recoverable, though it can be configured (via `panic=abort`) to always be non-recoverable. (The converse is not true: `panic=unwind` does not guarantee that all panics are recoverable, only that panicking via the `panic!` macro and similar standard library mechanisms is recoverable.)
51+
Panicking may either be recoverable or non-recoverable, though it can be configured (by choosing the `abort` panic runtime) to always be non-recoverable. (The converse is not true: the `unwind` runtime does not guarantee that all panics are recoverable, only that panicking via the `panic!` macro and similar standard library mechanisms is recoverable.)
3752

3853
r[panic.unwind.destruction]
39-
When panic recovery occurs, the runtime "unwinds" Rust frames, just as C++'s `throw` unwinds C++ frames, until the panic reaches the point of recovery (for instance at a thread boundary). This means that as the panic traverses Rust frames, live objects in those frames that [implement `Drop`][destructors] will have their `drop` methods called. Thus, when normal execution resumes, no-longer-accessible objects will have been "cleaned up" just as if they had gone out of scope normally.
54+
When panic recovery occurs, the `unwind` runtime "unwinds" Rust frames, just as C++'s `throw` unwinds C++ frames, until the panic reaches the point of recovery (for instance at a thread boundary). This means that as the panic traverses Rust frames, live objects in those frames that [implement `Drop`][destructors] will have their `drop` methods called. Thus, when normal execution resumes, no-longer-accessible objects will have been "cleaned up" just as if they had gone out of scope normally.
4055

4156
> [!NOTE]
4257
> As long as this guarantee of resource-cleanup is preserved, "unwinding" may be implemented without actually using the mechanism used by C++ for the target platform.
@@ -72,3 +87,4 @@ There are currently no guarantees about the behavior that occurs when a foreign
7287
[destructors]: destructors.md
7388
[runtime]: runtime.md
7489
[unwind-abi]: items/functions.md#unwinding
90+
[`-C panic`]: ../rustc/codegen-options/index.html#panic

0 commit comments

Comments
 (0)