11# Panic
22
3+ r[ panic]
4+
5+ r[ panic.intro]
36Rust provides a mechanism to prevent a function from returning normally, and
47instead "panic," which is a response to an error condition that is typically
58not expected to be recoverable within the context in which the error is
69encountered.
710
11+ r[ panic.lang-ops]
812Some language constructs, such as out-of-bounds [ array indexing] , panic
9- automatically. There are also language features that provide a level of control
13+ automatically.
14+
15+ r[ panic.control]
16+ There are also language features that provide a level of control
1017over panic behavior:
1118* A [ _ panic runtime_ ] ( #panic-runtimes ) defined how a panic is handled during
1219 runtime.
1320* [ FFI ABIs] ( items/functions.md#unwinding ) may alter how panics behave.
1421
15- > ** Note** : The standard library provides the capability to explicitly panic
22+ > [ !NOTE]
23+ > The standard library provides the capability to explicitly panic
1624> via the [ ` panic! ` macro] [ macro-panic ] .
1725
1826## Unwinding
1927
28+ r[ panic.unwind]
29+
30+ r[ panic.unwind.intro]
2031Panicking may either be recoverable or non-recoverable, though it can be
2132configured (via ` panic=abort ` ) to always be non-recoverable. (The converse is
2233not true: ` panic=unwind ` does not guarantee that all panics are recoverable,
2334only that panicking via the ` panic! ` macro and similar standard library
24- mechanisms is recoverable.) When panic recovery occurs, the runtime "unwinds"
25- Rust frames, just as C++'s ` throw ` unwinds C++ frames, until the panic reaches
35+ mechanisms is recoverable.)
36+
37+ r[ panic.unwind.destruction]
38+ When panic recovery occurs, the runtime "unwinds" Rust frames, just as C++'s ` throw ` unwinds C++ frames, until the panic reaches
2639the point of recovery (for instance at a thread boundary). This means that as
2740the panic traverses Rust frames, live objects in those frames that [ implement
2841` Drop ` ] [ destructors ] will have their ` drop ` methods called. Thus, when normal
2942execution resumes, no-longer-accessible objects will have been "cleaned up"
3043just as if they had gone out of scope normally.
3144
32- > ** Note** : As long as this guarantee of resource-cleanup is preserved,
45+ > [ !NOTE]
46+ > As long as this guarantee of resource-cleanup is preserved,
3347> "unwinding" may be implemented without actually using the mechanism used by
3448> C++ for the target platform.
3549
36- > ** Note** : The standard library provides two mechanisms for recovering from a panic,
50+ > [ !NOTE]
51+ > The standard library provides two mechanisms for recovering from a panic,
3752> [ ` catch_unwind ` ] [ fn-catch-unwind ] (which enables recovery within the
3853> panicking thread) and [ ` thread::spawn ` ] [ thread-spawn ] (which automatically
3954> sets up panic recovery for the spawned thread so that other threads may
4055> continue running).
4156
4257### Unwinding across FFI boundaries
4358
59+ r[ panic.unwind.ffi]
60+
61+ r[ panic.unwind.ffi.intro]
4462It is possible to unwind across FFI boundaries using an [ appropriate ABI
4563declaration] [ unwind-abi ] . While useful in certain cases, this creates unique
4664opportunities for undefined behavior, especially when multiple language runtimes
4765are involved.
4866
67+ r[ panic.unwind.ffi.undefined]
4968Unwinding with the wrong ABI is undefined behavior:
5069
5170* Causing an unwind into Rust code from a foreign function that was called via a
@@ -56,39 +75,46 @@ Unwinding with the wrong ABI is undefined behavior:
5675 another ABI that permits unwinding) from a runtime that does not support.
5776 unwinding, such as code compiled with GCC or Clang using ` -fno-exceptions `
5877
78+ r[ panic.unwind.ffi.catch-foreign]
5979Catching a foreign unwinding operation (such as a C++ exception) using
6080` catch_unwind ` , ` JoinHandle::join ` , or by letting it propagate all the way to a
6181Rust ` main() ` function will have one of two behaviors, and it is unspecified
6282which will occur:
6383* The process aborts.
6484* The function returns a ` Result::Err ` containing an opaque type.
6585
66- Note that Rust code compiled or linked with a different runtime counts as a
67- "foreign exception" for the purpose of this guarantee. Thus, a library that
68- uses ` panic! ` and is linked against one version of the Rust standard library,
69- invoked from an application that uses a different version of the standard
70- library, may cause the entire application to crash even if the library is only
71- used within a child thread.
86+ > [ !NOTE]
87+ > Rust code compiled or linked with a different runtime counts as a
88+ > "foreign exception" for the purpose of this guarantee. Thus, a library that
89+ > uses ` panic! ` and is linked against one version of the Rust standard library,
90+ > invoked from an application that uses a different version of the standard
91+ > library, may cause the entire application to crash even if the library is only
92+ > used within a child thread.
7293
94+ r[ panic.unwind.ffi.dipose-panic]
7395There are currently no guarantees about the behavior that occurs when a foreign
7496runtime attempts to dispose of, or rethrow, a Rust ` panic ` payload. In other
7597words, an unwind originated from a Rust runtime must either lead to termination
7698of the process or be caught by the same runtime.
7799
78100## Panic runtimes
79101
102+ r[ panic.runtime]
103+
80104The actual behavior and implementation of ` panic! ` is controlled by the _ panic
81105runtime_ .
82106
83- > ** Note** : The Rust standard library provides two panic runtimes:
107+ > [ !NOTE]
108+ > The Rust standard library provides two panic runtimes:
84109> ` panic_unwind ` (which unwinds the stack and is potentially recoverable) and
85110> ` panic_abort ` (which aborts the process and is non-recoverable). The default
86111> runtime depends on the target platform, but is generally ` panic_unwind ` on
87112> platforms with native support for C++ exceptions.
88113
89- When compiling code that is guaranteed to be linked to a non-recoverable panic
90- runtime, the optimizer may assume that unwinding across Rust frames is
91- impossible, which can result in both code-size and runtime speed improvements.
114+ > [ !NOTE]
115+ > When compiling code that is guaranteed to be linked to a non-recoverable panic
116+ > runtime, the optimizer may assume that unwinding across Rust frames is
117+ > impossible, which can result in both code-size and runtime speed improvements.
92118
93119See also the [ ` panic_handler ` attribute] ( runtime.md#the-panic_handler-attribute ) which can be used to change the behavior of panics.
94120
0 commit comments