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
//! Debugging a crash (exception) //! //! The `cortex-m-rt` crate provides functionality for this through a default //! exception handler. When an exception is hit, the default handler will //! trigger a breakpoint and in this debugging context the stacked registers //! are accessible. //! //! In you run the example below, you'll be able to inspect the state of your //! program under the debugger using these commands: //! //! ``` //! (gdb) # Stacked registers = program state during the crash //! (gdb) print/x *_sr //! $1 = cortex_m::exception::StackedRegisters { //! r0 = 0x2fffffff, //! r1 = 0x2fffffff, //! r2 = 0x0, //! r3 = 0x0, //! r12 = 0x0, //! lr = 0x8000443, //! pc = 0x8000190, //! xpsr = 0x61000200, //! } //! //! (gdb) # What exception was triggered? //! (gdb) print _e //! $2 = cortex_m::exception::Exception::HardFault //! //! (gdb) # Where did we come from? //! (gdb) print _e //! ``` //! //! ``` //! //! #![feature(used)] //! #![no_std] //! //! extern crate cortex_m; //! extern crate cortex_m_rt; //! //! use core::ptr; //! //! use cortex_m::asm; //! //! fn main() { //! // Read an invalid memory address //! unsafe { //! ptr::read_volatile(0x2FFF_FFFF as *const u32); //! } //! } //! //! // As we are not using interrupts, we just register a dummy catch all handler //! #[allow(dead_code)] //! #[used] //! #[link_section = ".rodata.interrupts"] //! static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; //! //! extern "C" fn default_handler() { //! asm::bkpt(); //! } //! ``` // Auto-generated. Do not modify.