1
1
# Panic
2
2
3
+ r[ panic]
4
+
5
+ r[ panic.intro]
3
6
Rust provides a mechanism to prevent a function from returning normally, and
4
7
instead "panic," which is a response to an error condition that is typically
5
8
not expected to be recoverable within the context in which the error is
6
9
encountered.
7
10
11
+ r[ panic.lang-ops]
8
12
Some 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
10
17
over panic behavior:
11
18
* A [ _ panic runtime_ ] ( #panic-runtimes ) defined how a panic is handled during
12
19
runtime.
13
20
* [ FFI ABIs] ( items/functions.md#unwinding ) may alter how panics behave.
14
21
15
- > ** Note** : The standard library provides the capability to explicitly panic
22
+ > [ !NOTE]
23
+ > The standard library provides the capability to explicitly panic
16
24
> via the [ ` panic! ` macro] [ macro-panic ] .
17
25
18
26
## Unwinding
19
27
28
+ r[ panic.unwind]
29
+
30
+ r[ panic.unwind.intro]
20
31
Panicking may either be recoverable or non-recoverable, though it can be
21
32
configured (via ` panic=abort ` ) to always be non-recoverable. (The converse is
22
33
not true: ` panic=unwind ` does not guarantee that all panics are recoverable,
23
34
only 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
26
39
the point of recovery (for instance at a thread boundary). This means that as
27
40
the panic traverses Rust frames, live objects in those frames that [ implement
28
41
` Drop ` ] [ destructors ] will have their ` drop ` methods called. Thus, when normal
29
42
execution resumes, no-longer-accessible objects will have been "cleaned up"
30
43
just as if they had gone out of scope normally.
31
44
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,
33
47
> "unwinding" may be implemented without actually using the mechanism used by
34
48
> C++ for the target platform.
35
49
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,
37
52
> [ ` catch_unwind ` ] [ fn-catch-unwind ] (which enables recovery within the
38
53
> panicking thread) and [ ` thread::spawn ` ] [ thread-spawn ] (which automatically
39
54
> sets up panic recovery for the spawned thread so that other threads may
40
55
> continue running).
41
56
42
57
### Unwinding across FFI boundaries
43
58
59
+ r[ panic.unwind.ffi]
60
+
61
+ r[ panic.unwind.ffi.intro]
44
62
It is possible to unwind across FFI boundaries using an [ appropriate ABI
45
63
declaration] [ unwind-abi ] . While useful in certain cases, this creates unique
46
64
opportunities for undefined behavior, especially when multiple language runtimes
47
65
are involved.
48
66
67
+ r[ panic.unwind.ffi.undefined]
49
68
Unwinding with the wrong ABI is undefined behavior:
50
69
51
70
* 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:
56
75
another ABI that permits unwinding) from a runtime that does not support.
57
76
unwinding, such as code compiled with GCC or Clang using ` -fno-exceptions `
58
77
78
+ r[ panic.unwind.ffi.catch-foreign]
59
79
Catching a foreign unwinding operation (such as a C++ exception) using
60
80
` catch_unwind ` , ` JoinHandle::join ` , or by letting it propagate all the way to a
61
81
Rust ` main() ` function will have one of two behaviors, and it is unspecified
62
82
which will occur:
63
83
* The process aborts.
64
84
* The function returns a ` Result::Err ` containing an opaque type.
65
85
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.
72
93
94
+ r[ panic.unwind.ffi.dipose-panic]
73
95
There are currently no guarantees about the behavior that occurs when a foreign
74
96
runtime attempts to dispose of, or rethrow, a Rust ` panic ` payload. In other
75
97
words, an unwind originated from a Rust runtime must either lead to termination
76
98
of the process or be caught by the same runtime.
77
99
78
100
## Panic runtimes
79
101
102
+ r[ panic.runtime]
103
+
80
104
The actual behavior and implementation of ` panic! ` is controlled by the _ panic
81
105
runtime_ .
82
106
83
- > ** Note** : The Rust standard library provides two panic runtimes:
107
+ > [ !NOTE]
108
+ > The Rust standard library provides two panic runtimes:
84
109
> ` panic_unwind ` (which unwinds the stack and is potentially recoverable) and
85
110
> ` panic_abort ` (which aborts the process and is non-recoverable). The default
86
111
> runtime depends on the target platform, but is generally ` panic_unwind ` on
87
112
> platforms with native support for C++ exceptions.
88
113
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.
92
118
93
119
See also the [ ` panic_handler ` attribute] ( runtime.md#the-panic_handler-attribute ) which can be used to change the behavior of panics.
94
120
0 commit comments