|
8 | 8 | //! debugger using these commands:
|
9 | 9 | //!
|
10 | 10 | //! ``` text
|
| 11 | +//! (gdb) continue |
| 12 | +//! Program received signal SIGTRAP, Trace/breakpoint trap. |
| 13 | +//! __bkpt () at asm/bkpt.s:3 |
| 14 | +//! 3 bkpt |
| 15 | +//! |
| 16 | +//! (gdb) finish |
| 17 | +//! Run till exit from #0 __bkpt () at asm/bkpt.s:3 |
| 18 | +//! Note: automatically using hardware breakpoints for read-only addresses. |
| 19 | +//! crash::hf (_ef=0x20004fa0) at examples/crash.rs:102 |
| 20 | +//! 99 asm::bkpt(); |
| 21 | +//! |
11 | 22 | //! (gdb) # Exception frame = program state during the crash
|
12 |
| -//! (gdb) print/x *ef |
13 |
| -//! $1 = cortex_m::exception::ExceptionFrame { |
14 |
| -//! r0 = 0x2fffffff, |
15 |
| -//! r1 = 0x2fffffff, |
16 |
| -//! r2 = 0x0, |
17 |
| -//! r3 = 0x0, |
18 |
| -//! r12 = 0x0, |
19 |
| -//! lr = 0x8000481, |
20 |
| -//! pc = 0x8000460, |
21 |
| -//! xpsr = 0x61000000, |
| 23 | +//! (gdb) print/x *_ef |
| 24 | +//! $1 = cortex_m_rt::ExceptionFrame { |
| 25 | +//! r0: 0x2fffffff, |
| 26 | +//! r1: 0x2fffffff, |
| 27 | +//! r2: 0x80006b0, |
| 28 | +//! r3: 0x80006b0, |
| 29 | +//! r12: 0x20000000, |
| 30 | +//! lr: 0x800040f, |
| 31 | +//! pc: 0x800066a, |
| 32 | +//! xpsr: 0x61000000 |
22 | 33 | //! }
|
23 | 34 | //!
|
24 | 35 | //! (gdb) # Where did we come from?
|
25 | 36 | //! (gdb) backtrace
|
26 |
| -//! #0 cortex_m_rt::default_handler (ef=0x20004f54) at (..) |
27 |
| -//! #1 <signal handler called> |
28 |
| -//! #2 0x08000460 in core::ptr::read_volatile<u32> (src=0x2fffffff) at (..) |
29 |
| -//! #3 0x08000480 in crash::main () at examples/crash.rs:68 |
| 37 | +//! #0 crash::hf (_ef=0x20004fa0) at examples/crash.rs:102 |
| 38 | +//! #1 0x080004ac in UserHardFault (ef=0x20004fa0) at <exception macros>:9 |
| 39 | +//! #2 <signal handler called> |
| 40 | +//! #3 0x0800066a in core::ptr::read_volatile (src=0x2fffffff) at /checkout/src/libcore/ptr.rs:452 |
| 41 | +//! #4 0x0800040e in crash::main () at examples/crash.rs:85 |
| 42 | +//! #5 0x08000456 in main () at <main macros>:3 |
30 | 43 | //!
|
31 | 44 | //! (gdb) # Nail down the location of the crash
|
32 |
| -//! (gdb) disassemble/m ef.pc |
33 |
| -//! Dump of assembler code for function core::ptr::read_volatile<u32>: |
34 |
| -//! 408 pub unsafe fn read_volatile<T>(src: *const T) -> T { |
35 |
| -//! 0x08000454 <+0>: sub sp, #20 |
36 |
| -//! 0x08000456 <+2>: mov r1, r0 |
37 |
| -//! 0x08000458 <+4>: str r0, [sp, #8] |
38 |
| -//! 0x0800045a <+6>: ldr r0, [sp, #8] |
39 |
| -//! 0x0800045c <+8>: str r0, [sp, #12] |
| 45 | +//! (gdb) disassemble/m _ef.pc |
| 46 | +//! Dump of assembler code for function core::ptr::read_volatile: |
| 47 | +//! 451 pub unsafe fn read_volatile<T>(src: *const T) -> T {} |
| 48 | +//! 0x08000662 <+0>: sub sp, #16 |
| 49 | +//! 0x08000664 <+2>: mov r1, r0 |
| 50 | +//! 0x08000666 <+4>: str r0, [sp, #8] |
40 | 51 | //!
|
41 |
| -//! 409 intrinsics::volatile_load(src) |
42 |
| -//! 0x0800045e <+10>: ldr r0, [sp, #12] |
43 |
| -//! 0x08000460 <+12>: ldr r0, [r0, #0] |
44 |
| -//! 0x08000462 <+14>: str r0, [sp, #16] |
45 |
| -//! 0x08000464 <+16>: ldr r0, [sp, #16] |
46 |
| -//! 0x08000466 <+18>: str r1, [sp, #4] |
47 |
| -//! 0x08000468 <+20>: str r0, [sp, #0] |
48 |
| -//! 0x0800046a <+22>: b.n 0x800046c <core::ptr::read_volatile<u32>+24> |
| 52 | +//! 452 intrinsics::volatile_load(src) |
| 53 | +//! 0x08000668 <+6>: ldr r0, [sp, #8] |
| 54 | +//! 0x0800066a <+8>: ldr r0, [r0, #0] |
| 55 | +//! 0x0800066c <+10>: str r0, [sp, #12] |
| 56 | +//! 0x0800066e <+12>: ldr r0, [sp, #12] |
| 57 | +//! 0x08000670 <+14>: str r1, [sp, #4] |
| 58 | +//! 0x08000672 <+16>: str r0, [sp, #0] |
| 59 | +//! 0x08000674 <+18>: b.n 0x8000676 <core::ptr::read_volatile+20> |
49 | 60 | //!
|
50 |
| -//! 410 } |
51 |
| -//! 0x0800046c <+24>: ldr r0, [sp, #0] |
52 |
| -//! 0x0800046e <+26>: add sp, #20 |
53 |
| -//! 0x08000470 <+28>: bx lr |
| 61 | +//! 453 } |
| 62 | +//! 0x08000676 <+20>: ldr r0, [sp, #0] |
| 63 | +//! 0x08000678 <+22>: add sp, #16 |
| 64 | +//! 0x0800067a <+24>: bx lr |
54 | 65 | //!
|
55 | 66 | //! End of assembler dump.
|
56 | 67 | //! ```
|
57 | 68 | //!
|
58 | 69 | //! ---
|
59 | 70 |
|
60 |
| -#![feature(used)] |
| 71 | +#![no_main] |
61 | 72 | #![no_std]
|
62 | 73 |
|
63 | 74 | extern crate cortex_m;
|
64 |
| -extern crate cortex_m_rt; |
| 75 | +#[macro_use] |
| 76 | +extern crate cortex_m_rt as rt; |
65 | 77 | extern crate panic_abort; // panicking behavior
|
66 | 78 |
|
67 | 79 | use core::ptr;
|
68 | 80 |
|
69 | 81 | use cortex_m::asm;
|
| 82 | +use rt::ExceptionFrame; |
| 83 | + |
| 84 | +main!(main); |
70 | 85 |
|
71 |
| -fn main() { |
72 |
| - // Read an invalid memory address |
| 86 | +#[inline(always)] |
| 87 | +fn main() -> ! { |
73 | 88 | unsafe {
|
74 | 89 | ptr::read_volatile(0x2FFF_FFFF as *const u32);
|
75 | 90 | }
|
| 91 | + |
| 92 | + loop {} |
| 93 | +} |
| 94 | + |
| 95 | +exception!(DefaultHandler, dh); |
| 96 | + |
| 97 | +#[inline(always)] |
| 98 | +fn dh(_nr: u8) { |
| 99 | + asm::bkpt(); |
76 | 100 | }
|
77 | 101 |
|
78 |
| -// As we are not using interrupts, we just register a dummy catch all handler |
79 |
| -#[link_section = ".vector_table.interrupts"] |
80 |
| -#[used] |
81 |
| -static INTERRUPTS: [extern "C" fn(); 240] = [default_handler; 240]; |
| 102 | +exception!(HardFault, hf); |
82 | 103 |
|
83 |
| -extern "C" fn default_handler() { |
| 104 | +#[inline(always)] |
| 105 | +fn hf(_ef: &ExceptionFrame) -> ! { |
84 | 106 | asm::bkpt();
|
| 107 | + |
| 108 | + loop {} |
85 | 109 | }
|
| 110 | + |
| 111 | +interrupts!(DefaultHandler); |
0 commit comments