Module cortex_m_quickstart::examples::_3_crash [] [src]

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();
}