Rust debugging doesn't stop at the breakpoints when debugging stm32f407 via openocd and gdb


I have a problem debugging an stm32f407vet6 board and rust code. The point of the problem is that GDB ignores breakpoints. After setting breakpoints and executing the "continue" command in gdb, the program continues to ignore all breakpoints. The only way to stop the program running is to cause an interrupt using the "ctrl + c" command. After this command, the board stops its execution on the line currently being executed. I have tried to set breakpoints on all lines where I can set them, but all the attempts are unsuccessful.

$ openocd
Open On-Chip Debugger 0.10.0 (2020-07-01) []
Licensed under GNU GPL v2
libusb1 09e75e98b4d9ea7909e8837b7a3f00dda4589dc3
For bug reports, read
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 2000 kHz
Error: libusb_open() failed with LIBUSB_ERROR_NOT_SUPPORTED
Info : STLINK V2J35S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 6.436364
Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 3333
Info : Listening on port 3333 for gdb connections
$ arm-none-eabi-gdb -q target\thumbv7em-none-eabihf\debug\test_blink
Reading symbols from target\thumbv7em-none-eabihf\debug\test_blink...                                                                                                        
(gdb) target remote :3333                                                                                                                                                    
Remote debugging using :3333                                                                                                                                                 
0x00004070 in core::ptr::read_volatile (src=0xe000e010) at C:\Users\User\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\src/libcore/ptr/   
1005    pub unsafe fn read_volatile<T>(src: *const T) -> T {                                                                                                                 
(gdb) load                                                                                                                                                                   
Loading section .vector_table, size 0x1a8 lma 0x0                                                                                                                            
Loading section .text, size 0x47bc lma 0x1a8                                                                                                                                 
Loading section .rodata, size 0xbf0 lma 0x4970                                                                                                                               
Start address 0x47a2, load size 21844                                                                                                                                        
Transfer rate: 100 KB/sec, 5461 bytes/write.                                                                                                                                 
(gdb) b main                                                                                                                                                                 
Breakpoint 1 at 0x1f2: file src\, line 15.                                                                                                                            
(gdb) continue                                                                                                                                                               
Program received signal SIGINT, Interrupt.                                                                                                                                   
0x00001530 in cortex_m::peripheral::syst::<impl cortex_m::peripheral::SYST>::has_wrapped (self=0x1000fc6c)                                                                   
    at C:\Users\User\.cargo\registry\src\\cortex-m-0.6.3\src\peripheral/                                                               
135         pub fn has_wrapped(&mut self) -> bool {                                                                                                                          
(gdb) bt                                                                                                                              
#0  0x00001530 in cortex_m::peripheral::syst::<impl cortex_m::peripheral::SYST>::has_wrapped (self=0x1000fc6c)                        
    at C:\Users\User\.cargo\registry\src\\cortex-m-0.6.3\src\peripheral/                        
#1  0x00003450 in <stm32f4xx_hal::delay::Delay as embedded_hal::blocking::delay::DelayUs<u32>>::delay_us (self=0x1000fc6c, us=500000) 
    at C:\Users\User\.cargo\registry\src\\stm32f4xx-hal-0.8.3\src/                              
#2  0x0000339e in <stm32f4xx_hal::delay::Delay as embedded_hal::blocking::delay::DelayMs<u32>>::delay_ms (self=0x1000fc6c, ms=500)    
    at C:\Users\User\.cargo\registry\src\\stm32f4xx-hal-0.8.3\src/                              
#3  0x00000318 in test_blink::__cortex_m_rt_main () at src\                                                                 
#4  0x000001f6 in main () at src\

memory.x file:

  /* NOTE 1 K = 1 KiBi = 1024 bytes */
  /* TODO Adjust these memory regions to match your device memory layout */
  /* These values correspond to the LM3S6965, one of the few devices QEMU can emulate */
  CCMRAM : ORIGIN = 0x10000000, LENGTH = 64K
  RAM : ORIGIN = 0x20000000, LENGTH = 128K
  FLASH : ORIGIN = 0x00000000, LENGTH = 512K

/* This is where the call stack will be allocated. */
/* The stack is of the full descending type. */
/* You may want to use this variable to locate the call stack and static
   variables in different memory regions. Below is shown the default value */

/* You can use this symbol to customize the location of the .text section */
/* If omitted the .text section will be placed right after the .vector_table
   section */
/* This is required only on microcontrollers that store some configuration right
   after the vector table */
/* _stext = ORIGIN(FLASH) + 0x400; */

/* Example of putting non-initialized variables into custom RAM locations. */
/* This assumes you have defined a region RAM2 above, and in the Rust
   sources added the attribute `#[link_section = ".ram2bss"]` to the data
   you want to place there. */
/* Note that the section will not be zero-initialized by the runtime! */
     .ram2bss (NOLOAD) : ALIGN(4) {
       . = ALIGN(4);
     } > RAM2
   } INSERT AFTER .bss;

openocd.cfg file:

# Sample OpenOCD configuration for the STM32F3DISCOVERY development board

# Depending on the hardware revision you got you'll have to pick ONE of these
# interfaces. At any time only one interface should be commented out.

# Revision C (newer revision)
source [find interface/stlink.cfg]

# Revision A and B (older revisions)
# source [find interface/stlink-v2.cfg]

source [find target/stm32f4x.cfg]

# use hardware reset, connect under reset
# reset_config none separate file:


// Halt on panic
#[allow(unused_extern_crates)] // NOTE(allow) bug rust-lang/rust#53964
extern crate panic_halt; // panic handler

use cortex_m;
use cortex_m_rt::entry;
use stm32f4xx_hal as hal;

use crate::hal::{prelude::*, stm32};

fn main() -> ! {
    if let (Some(dp), Some(cp)) = (
    ) {
        let rcc = dp.RCC.constrain();
        let clocks = rcc

        let mut delay = hal::delay::Delay::new(cp.SYST, clocks);

        let gpioa = dp.GPIOA.split();

        let mut l1 = gpioa.pa6.into_push_pull_output();
        let mut l2 = gpioa.pa7.into_push_pull_output();

        loop {

    loop {}

Cargo.toml file:

name = "test_blink"
version = "0.1.0"
authors = ["Alex"]
edition = "2018"

# See more keys and their definitions at

embedded-hal = "0.2"
nb = "0.1.2"
cortex-m = "0.6"
cortex-m-rt = "0.6"
# Panic behaviour, see for alternatives
panic-halt = "0.2"

version = "0.8.3"
features = ["rt", "stm32f407"]

I am new to rust embedded and maybe I have done something wrong, but I have already tried all the options I can find on the Internet. At first I thought it was a problem with the cortex-debug plugin for vscode and even created the issue, but the guys couldn't help me because the problem is obviously not on their side.

Debugging "C" code in cubeIDE works, so I dare to assume that the problem is somewhere in rust--gdb--openocd. Perhaps I am missing something, but unfortunately I cannot find it myself yet.

I would appreciate any resources or ideas to solve this problem.

asked on Stack Overflow Aug 16, 2020 by muttering-oldman • edited Aug 16, 2020 by muttering-oldman

1 Answer


I'm hoping you checked out this resources: Discovery - debug

From your screen-grab of arm-none-eabi-gdb it does indeed look it it did not hit the break point.

you should have seen this message afterwards:

Note: automatically using hardware breakpoints for read-only addresses. Breakpoint 1, main () at ...

Did you compile your source with symbols, and unoptimised?

Your config all looks right to me otherwise.

answered on Stack Overflow Sep 23, 2020 by xx1xx

User contributions licensed under CC BY-SA 3.0