Skip to content

Commit 9bf58c7

Browse files
Kyle StrandBatmanAoD
authored andcommitted
trying to define panicking from first principles
1 parent 76f8436 commit 9bf58c7

File tree

5 files changed

+62
-48
lines changed

5 files changed

+62
-48
lines changed

src/expressions/array-expr.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Just as with methods, Rust will also insert dereference operations on `a` repeat
5353

5454
Indices are zero-based for arrays and slices.
5555
Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value.
56-
Otherwise a check will be performed at run-time that will put the thread in a _panicked state_ if it fails.
56+
Otherwise a check will be performed at run-time that will put the thread in a [_panicked state_][panic] if it fails.
5757

5858
```rust,should_panic
5959
// lint is deny by default.
@@ -86,3 +86,4 @@ The array index expression can be implemented for types other than arrays and sl
8686
[memory location]: ../expressions.md#place-expressions-and-value-expressions
8787
[path]: path-expr.md
8888
[slice]: ../types/slice.md
89+
[panic]: ../panic.md

src/items/functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ other ABI supported by the language implementation.
226226
> **Note**: The LLVM backend of the `rustc` implementation
227227
> aborts the process by executing an illegal instruction.
228228
229-
[panic-modes]: ../panic-runtime.md
229+
[panic-modes]: ../panic.md#panic-runtime
230230

231231
## Const functions
232232

src/linkage.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,4 +228,4 @@ runtime, so this prohibition does not apply to projects compiled with Cargo.
228228
[`cfg` attribute `target_feature` option]: conditional-compilation.md#target_feature
229229
[configuration option]: conditional-compilation.md
230230
[procedural macros]: procedural-macros.md
231-
[panic-runtime]: panic-runtime.md
231+
[panic-runtime]: panic.md#panic-runtime

src/panic-runtime.md

Lines changed: 0 additions & 45 deletions
This file was deleted.

src/panic.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Panic
2+
3+
Rust provides the ability to "panic" upon encountering a runtime error that is
4+
not part of a function's signature; such an error is typically not expected to
5+
be recoverable within the context in which the error is encountered.
6+
7+
> The Standard Library provides this capability via the [`panic!` macro][macro-panic].
8+
9+
Although it is not part of the core language, panics interact with several core
10+
language features; for instance, out-of-bounds array indexing using the
11+
`array[index]` syntax will automatically panic.
12+
13+
[macro-panic]: ../std/macro.panic.html
14+
[fn-catch-unwind]: ../std/panic/fn.catch_unwind.html
15+
[join]: ../std/thread/struct.JoinHandle.html#method.join
16+
17+
## Unwinding
18+
19+
By default, the `panic!` macro unwinds Rust frames, just as C++'s `throw`
20+
unwinds C++ frames. This means that as the panic traverses Rust frames, live
21+
objects in those frames that implement `Drop` will have their `drop` methods
22+
called. It also enables the runtime to recover from the panic rather than
23+
terminating execution.
24+
25+
> The Standard Library provides two mechanisms for recovering from a panic,
26+
> [`catch_unwind`][fn-catch-unwind] (which enables a thread to recover) and
27+
> [`JoinHandle::join`][join] (which enables a process to recover without
28+
> recovering the thread state).
29+
30+
## Panic runtimes
31+
[top]: #panic-runtimes
32+
33+
The actual behavior of `panic!` is controlled by the _panic runtime_. The Rust
34+
standard library provides two panic runtimes: `panic_unwind` (the default) and
35+
`panic_abort`, which immediately aborts the process. When compiling code that
36+
is guaranteed (via a [compiler option][rustc-codegen]), the optimizer may
37+
assume that unwinding across Rust frames is impossible, which can result in
38+
both code-size and runtime speed improvements.
39+
40+
### `rustc` codegen and linking
41+
[rustc-codegen]: #rustc-codegen
42+
43+
`rustc` provides two supported runtime strategies:
44+
45+
* `-C panic=unwind` - this links against `panic_unwind` and ensures that
46+
unwinding across the compiled frames will perform all appropriate clean-up.
47+
In particular, `drop` will be called for live `Drop` objects.
48+
* `-C panic=abort` - this links against `panic_abort`, and optimizes with the
49+
assumption that frames cannot be unwound. Since unwinding does not occur with
50+
this runtime, it is impossible to catch a `panic!` using `catch_unwind`.
51+
52+
This codegen option will default to `unwind` if not specified, and the value is
53+
encoded into the crate metadata.
54+
55+
Linking against the actual panic runtime is performed lazily, so that if
56+
different crates specify different runtimes, the `panic_abort` runtime is
57+
preferred. This ensures that `panic!` cannot cause a soundness hole by
58+
unwinding across Rust frames compiled with `panic=abort`.

0 commit comments

Comments
 (0)