]> git.proxmox.com Git - rustc.git/blame - src/doc/embedded-book/src/start/panicking.md
New upstream version 1.49.0+dfsg1
[rustc.git] / src / doc / embedded-book / src / start / panicking.md
CommitLineData
9fa01778
XL
1# Panicking
2
3Panicking is a core part of the Rust language. Built-in operations like indexing
4are runtime checked for memory safety. When out of bounds indexing is attempted
5this results in a panic.
6
7In the standard library panicking has a defined behavior: it unwinds the stack
8of the panicking thread, unless the user opted for aborting the program on
9panics.
10
532ac7d7
XL
11In programs without standard library, however, the panicking behavior is left
12undefined. A behavior can be chosen by declaring a `#[panic_handler]` function.
13This function must appear exactly *once* in the dependency graph of a program,
14and must have the following signature: `fn(&PanicInfo) -> !`, where [`PanicInfo`]
15is a struct containing information about the location of the panic.
9fa01778
XL
16
17[`PanicInfo`]: https://doc.rust-lang.org/core/panic/struct.PanicInfo.html
18
19Given that embedded systems range from user facing to safety critical (cannot
20crash) there's no one size fits all panicking behavior but there are plenty of
21commonly used behaviors. These common behaviors have been packaged into crates
22that define the `#[panic_handler]` function. Some examples include:
23
24- [`panic-abort`]. A panic causes the abort instruction to be executed.
25- [`panic-halt`]. A panic causes the program, or the current thread, to halt by
26 entering an infinite loop.
27- [`panic-itm`]. The panicking message is logged using the ITM, an ARM Cortex-M
28 specific peripheral.
29- [`panic-semihosting`]. The panicking message is logged to the host using the
30 semihosting technique.
31
32[`panic-abort`]: https://crates.io/crates/panic-abort
33[`panic-halt`]: https://crates.io/crates/panic-halt
34[`panic-itm`]: https://crates.io/crates/panic-itm
35[`panic-semihosting`]: https://crates.io/crates/panic-semihosting
36
37You may be able to find even more crates searching for the [`panic-handler`]
38keyword on crates.io.
39
40[`panic-handler`]: https://crates.io/keywords/panic-handler
41
42A program can pick one of these behaviors simply by linking to the corresponding
43crate. The fact that the panicking behavior is expressed in the source of
44an application as a single line of code is not only useful as documentation but
45can also be used to change the panicking behavior according to the compilation
46profile. For example:
47
48``` rust,ignore
49#![no_main]
50#![no_std]
51
52// dev profile: easier to debug panics; can put a breakpoint on `rust_begin_unwind`
53#[cfg(debug_assertions)]
72b1a166 54use panic_halt as _;
9fa01778
XL
55
56// release profile: minimize the binary size of the application
57#[cfg(not(debug_assertions))]
72b1a166 58use panic_abort as _;
9fa01778
XL
59
60// ..
61```
62
63In this example the crate links to the `panic-halt` crate when built with the
64dev profile (`cargo build`), but links to the `panic-abort` crate when built
65with the release profile (`cargo build --release`).
66
72b1a166
FG
67> The `use panic_abort as _;` form of the `use` statement is used to ensure the `panic_abort` panic handler is
68> included in our final executable while making it clear to the compiler that we won't explicitly use anything from
69> the crate. Without the `as _` rename, the compiler would warn that we have an unused import.
70> Sometimes you might see `extern crate panic_abort` instead, which is an older style used before the
71> 2018 edition of Rust, and should now only be used for "sysroot" crates (those distributed with Rust itself) such
72> as `proc_macro`, `alloc`, `std`, and `test`.
73
9fa01778
XL
74## An example
75
76Here's an example that tries to index an array beyond its length. The operation
77results in a panic.
78
532ac7d7 79```rust,ignore
9fa01778
XL
80#![no_main]
81#![no_std]
82
72b1a166 83use panic_semihosting as _;
9fa01778
XL
84
85use cortex_m_rt::entry;
86
87#[entry]
88fn main() -> ! {
89 let xs = [0, 1, 2];
90 let i = xs.len() + 1;
91 let _y = xs[i]; // out of bounds access
92
93 loop {}
94}
95```
96
97This example chose the `panic-semihosting` behavior which prints the panic
98message to the host console using semihosting.
99
100``` console
101$ cargo run
102 Running `qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb (..)
103panicked at 'index out of bounds: the len is 3 but the index is 4', src/main.rs:12:13
104```
105
106You can try changing the behavior to `panic-halt` and confirm that no message is
107printed in that case.