      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118

    //! Debugging a crash (exception)
    //!
    //! Most crash conditions trigger a hard fault exception, whose handler is defined via
    //! `exception!(HardFault, ..)`. The `HardFault` handler has access to the exception frame, a
    //! snapshot of the CPU registers at the moment of the exception.
    //!
    //! This program crashes and the `HardFault` handler prints to the console the contents of the
    //! `ExceptionFrame` and then triggers a breakpoint. From that breakpoint one can see the backtrace
    //! that led to the exception.
    //!
    //! ``` text
    //! (gdb) continue
    //! Program received signal SIGTRAP, Trace/breakpoint trap.
    //! __bkpt () at asm/bkpt.s:3
    //! 3         bkpt
    //!
    //! (gdb) backtrace
    //! #0  __bkpt () at asm/bkpt.s:3
    //! #1  0x080030b4 in cortex_m::asm::bkpt () at $$/cortex-m-0.5.0/src/asm.rs:19
    //! #2  rust_begin_unwind (args=..., file=..., line=99, col=5) at $$/panic-semihosting-0.2.0/src/lib.rs:87
    //! #3  0x08001d06 in core::panicking::panic_fmt () at libcore/panicking.rs:71
    //! #4  0x080004a6 in crash::hard_fault (ef=0x20004fa0) at examples/crash.rs:99
    //! #5  0x08000548 in UserHardFault (ef=0x20004fa0) at <exception macros>:10
    //! #6  0x0800093a in HardFault () at asm.s:5
    //! Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    //! ```
    //!
    //! In the console output one will find the state of the Program Counter (PC) register at the time
    //! of the exception.
    //!
    //! ``` text
    //! panicked at 'HardFault at ExceptionFrame {
    //!     r0: 0x2fffffff,
    //!     r1: 0x2fffffff,
    //!     r2: 0x080051d4,
    //!     r3: 0x080051d4,
    //!     r12: 0x20000000,
    //!     lr: 0x08000435,
    //!     pc: 0x08000ab6,
    //!     xpsr: 0x61000000
    //! }', examples/crash.rs:106:5
    //! ```
    //!
    //! This register contains the address of the instruction that caused the exception. In GDB one can
    //! disassemble the program around this address to observe the instruction that caused the
    //! exception.
    //!
    //! ``` text
    //! (gdb) disassemble/m 0x08000ab6
    //! Dump of assembler code for function core::ptr::read_volatile:
    //! 451     pub unsafe fn read_volatile<T>(src: *const T) -> T {
    //!    0x08000aae <+0>:     sub     sp, #16
    //!    0x08000ab0 <+2>:     mov     r1, r0
    //!    0x08000ab2 <+4>:     str     r0, [sp, #8]
    //!
    //! 452         intrinsics::volatile_load(src)
    //!    0x08000ab4 <+6>:     ldr     r0, [sp, #8]
    //! -> 0x08000ab6 <+8>:     ldr     r0, [r0, #0]
    //!    0x08000ab8 <+10>:    str     r0, [sp, #12]
    //!    0x08000aba <+12>:    ldr     r0, [sp, #12]
    //!    0x08000abc <+14>:    str     r1, [sp, #4]
    //!    0x08000abe <+16>:    str     r0, [sp, #0]
    //!    0x08000ac0 <+18>:    b.n     0x8000ac2 <core::ptr::read_volatile+20>
    //!
    //! 453     }
    //!    0x08000ac2 <+20>:    ldr     r0, [sp, #0]
    //!    0x08000ac4 <+22>:    add     sp, #16
    //!    0x08000ac6 <+24>:    bx      lr
    //!
    //! End of assembler dump.
    //! ```
    //!
    //! `ldr r0, [r0, #0]` caused the exception. This instruction tried to load (read) a 32-bit word
    //! from the address stored in the register `r0`. Looking again at the contents of `ExceptionFrame`
    //! we see that the `r0` contained the address `0x2FFF_FFFF` when this instruction was executed.
    //!
    //! ---
    //!
    //! ```
    //!
    //! #![no_main]
    //! #![no_std]
    //!
    //! extern crate cortex_m;
    //! #[macro_use]
    //! extern crate cortex_m_rt as rt;
    //! extern crate panic_semihosting;
    //!
    //! use core::ptr;
    //!
    //! use rt::ExceptionFrame;
    //!
    //! entry!(main);
    //!
    //! fn main() -> ! {
    //!     unsafe {
    //!         // read an address outside of the RAM region; causes a HardFault exception
    //!         ptr::read_volatile(0x2FFF_FFFF as *const u32);
    //!     }
    //!
    //!     loop {}
    //! }
    //!
    //! // define the hard fault handler
    //! exception!(HardFault, hard_fault);
    //!
    //! fn hard_fault(ef: &ExceptionFrame) -> ! {
    //!     panic!("HardFault at {:#?}", ef);
    //! }
    //!
    //! // define the default exception handler
    //! exception!(*, default_handler);
    //!
    //! fn default_handler(irqn: i16) {
    //!     panic!("Unhandled exception (IRQn = {})", irqn);
    //! }
    //! ```
    // Auto-generated. Do not modify.

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)