Debugging STM32 with GDB: 10 Powerful Steps to Master Embedded Debugging Easily

0b63979cd9494aa401d1fce2d73bb002
On: November 9, 2025
Debugging STM32 with GDB

Learn Debugging STM32 with GDB step-by-step. Master STM32 debugging, breakpoints, memory inspection embedded firmware troubleshooting

If you’ve ever worked on an STM32 project and your code didn’t run the way you expected, you know the pain of staring at an LED that refuses to blink or a UART that stays silent. That’s when Debugging STM32 with GDB becomes your best friend. It’s not magic — it’s a practical, structured way to find what’s really going on inside your microcontroller.

This guide will walk you step by step through Debugging STM32 with GDB, even if you’ve never used a debugger before. By the end, you’ll be confident enough to catch bugs, step through code, inspect memory, and make sense of your embedded system’s behavior.

1. What Does Debugging STM32 with GDB Actually Mean?

When we talk about Debugging STM32 with GDB, we’re talking about using the GNU Debugger (GDB) to analyze and control the execution of programs running on STM32 microcontrollers. STM32 chips use ARM Cortex-M cores, and GDB is capable of communicating with them through a debug interface like SWD (Serial Wire Debug).

In simpler terms, Debugging STM32 with GDB lets you:

  • Pause your program at any point.
  • Inspect what’s happening in memory.
  • Watch variable values in real-time.
  • Step through instructions line by line.
  • Find out why your firmware isn’t behaving as expected.

Unlike the old-school method of “LED blinking” or “printf debugging,” Debugging STM32 with GDB gives you direct access to the microcontroller’s brain. You see the program’s real state instead of guessing from its symptoms.

2. Why You Need Debugging STM32 with GDB

It doesn’t matter how skilled you are — bugs happen. Maybe a pointer goes wild, a peripheral doesn’t initialize properly, or your code crashes without warning. In embedded systems, you can’t always rely on console logs. That’s why Debugging STM32 with GDB is so important.

Here’s why it’s worth learning:

  1. Visibility: You can see exactly what the CPU is executing and what’s stored in registers or RAM.
  2. Control: You can stop, continue, or step through your program at will.
  3. Efficiency: It saves you hours of trial and error.
  4. Reliability: You catch logic errors early before they become hidden hardware issues.
  5. Scalability: Once you understand Debugging STM32 with GDB, the same knowledge applies to nearly all ARM Cortex-M devices.

Learning Debugging STM32 with GDB is like learning to look under the hood of your microcontroller instead of just guessing what’s wrong.

3. Tools You’ll Need for Debugging STM32 with GDB

Before jumping into commands, let’s talk about the basic setup. To perform Debugging STM32 with GDB, you’ll need a few essential tools:

  1. STM32 Microcontroller Board
    Any STM32 board will do — for example, STM32F4, STM32F1, STM32F7, etc.
  2. Debugger/Programmer
    A ST-LINK or J-Link device is required to connect your computer to the board via the SWD or JTAG interface.
  3. Toolchain with GDB Support
    You’ll need arm-none-eabi-gdb, which is part of the GNU Arm Embedded Toolchain.
  4. GDB Server
    This acts as the bridge between your board and GDB. You can use:
    • OpenOCD (Open On-Chip Debugger)
    • ST-LINK GDB Server
  5. Firmware with Debug Symbols
    Always compile your code with the -g flag to include debug information. Without it, GDB can’t show you variable names or line numbers.

Once you have these tools ready, you’re set to start Debugging STM32 with GDB.

4. Setting Up Your Environment for Debugging STM32 with GDB

Let’s go step by step.

Step 1: Build with Debug Info

When compiling your STM32 firmware, make sure your compiler flags include:

-g -O0

The -g flag adds debugging information, and -O0 disables optimization so the debugger matches your code line-by-line.

Step 2: Flash Your Firmware

Flash your .elf or .bin file to your STM32 using STM32CubeProgrammer or OpenOCD. Example:

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program build/main.elf verify reset exit"

Step 3: Start the GDB Server

Now run OpenOCD or your ST-LINK GDB server:

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg

It will wait for GDB to connect on port 3333.

Step 4: Connect GDB to Your Board

Open another terminal and run:

arm-none-eabi-gdb build/main.elf
(gdb) target remote localhost:3333

Congratulations — you’ve officially connected to your STM32!
You’re now in the world of Debugging STM32 with GDB.

5. Essential Commands for Debugging STM32 with GDB

Let’s explore the core commands that make Debugging STM32 with GDB powerful.

PurposeGDB Command
Stop the targetmonitor reset halt
Set a breakpointbreak main
Run programcontinue
Step into a functionstep
Step over a linenext
View variablesprint variable_name
View registersinfo registers
Examine memoryx /x address
Backtrace call stackbt
Watch variablewatch variable_name
Remove all breakpointsdelete
Exit GDBquit

These are your bread and butter during Debugging STM32 with GDB. You can do everything from pausing your MCU mid-execution to inspecting the contents of flash and RAM.

6. How Debugging STM32 with GDB Works Behind the Scenes

Here’s what’s actually happening when you debug:

  1. Your firmware runs on the STM32.
  2. OpenOCD or ST-LINK server talks to the hardware over SWD or JTAG.
  3. GDB communicates with the server over TCP (usually port 3333).
  4. When you send a command in GDB, the server halts the CPU, reads registers, or modifies memory.

That’s the magic of Debugging STM32 with GDB — you’re controlling the processor remotely at the hardware level.

7. Common Problems During Debugging STM32 with GDB

Even the best setup can run into issues. Here are common problems (and how to fix them):

1. GDB Won’t Connect

Check that the GDB server is running and the correct port (usually 3333) is being used.

2. Breakpoints Not Working

Ensure your firmware includes debug symbols (-g) and isn’t heavily optimized.

3. Variables Show as “”

This happens when compiler optimization removes variables. Rebuild with -O0.

4. Random Disconnects

Use a good-quality USB cable and make sure your debugger’s firmware is up to date.

5. MCU Doesn’t Halt

Try monitor reset halt to ensure the CPU stops before debugging.

Learning these small fixes will make your Debugging STM32 with GDB journey smoother.

8. Advanced Techniques in Debugging STM32 with GDB

Once you’re comfortable with basic commands, you can explore advanced features.

Hardware Watchpoints

You can monitor a variable’s value in real-time:

(gdb) watch counter

The debugger halts whenever counter changes — perfect for catching rogue variables.

Disassembly View

You can see what instructions are running:

(gdb) disassemble

Useful when you want to correlate C code with machine instructions.

Breakpoints by Address

You can break at a specific memory address:

(gdb) break *0x08001234

Script Automation

You can write .gdbinit files with predefined commands to automate debugging sessions. For example, you can automatically connect, reset, and load breakpoints at startup.

All these features make Debugging STM32 with GDB far more powerful than any GUI-based approach.

9. Real-World Example of Debugging STM32 with GDB

Let’s say your PWM output isn’t working. You suspect the timer isn’t initializing correctly.

  1. Set a breakpoint at MX_TIM2_Init().
  2. Run the program: (gdb) continue
  3. When it hits the breakpoint, step through the function using next.
  4. Print register values: (gdb) print htim2.Instance->CR1
  5. If CR1 doesn’t show the expected configuration, you’ve found the bug.
  6. Fix the code, rebuild, flash, and continue Debugging STM32 with GDB.

This method works for peripherals like UART, SPI, I2C, or even FreeRTOS task bugs. Once you learn Debugging STM32 with GDB, you’ll spend less time guessing and more time solving.

10. Tips for Better Debugging STM32 with GDB

  1. Use Unoptimized Builds First
    Start with -O0 for better visibility, then switch to optimized builds later.
  2. Understand Your Memory Map
    Know which addresses belong to flash, SRAM, and peripherals.
  3. Combine with IDEs
    Tools like STM32CubeIDE or VS Code can act as frontends for GDB. The core still runs on Debugging STM32 with GDB, but you get a GUI.
  4. Keep Sessions Short
    Long debug sessions can hang the board. Regularly reset the MCU.
  5. Learn Hot Commands
    Memorize 10–15 essential commands. It saves tons of time.
  6. Comment Your Fixes
    Document what caused the bug. It’s part of professional embedded debugging.

11. Why GDB Is a Must-Have for Every Embedded Developer

The reason developers love Debugging STM32 with GDB is simple — it’s fast, flexible, and reliable. You’re not locked into a single IDE, and it works across platforms (Windows, Linux, macOS).

Plus, once you learn the core commands, you can debug any ARM Cortex-M board. It’s like having a universal translator for your firmware.

If you want to master embedded development, learning Debugging STM32 with GDB isn’t optional — it’s essential.

12. Wrapping It Up

Debugging STM32 with GDB might sound intimidating at first, but once you understand the flow — compiling with debug symbols, connecting with OpenOCD, and running commands — it becomes second nature. You’ll find bugs faster, understand your firmware deeply, and become a more confident embedded engineer.

So grab your STM32 board, open your terminal, start the GDB server, and dive in. The first time you pause execution right at the bug’s location, you’ll realize how powerful this tool really is.

Debugging STM32 with GDB isn’t just a skill — it’s a superpower for embedded developers.

Let’s take a simple C program for STM32 and walk through how to perform Debugging STM32 with GDB step by step.

Step 1: Example C Program

Here’s a small example C program that toggles an LED every second but has a bug we’ll debug using GDB.

#include "stm32f4xx.h"

void delay(volatile uint32_t count) {
    while (count--) {
        // simple delay loop
    }
}

int main(void) {
    RCC->AHB1ENR |= (1 << 3); // Enable GPIOD clock (for STM32F4 Discovery)

    GPIOD->MODER |= (1 << 24); // Set PD12 as output

    uint8_t toggle = 0;

    while (1) {
        if (toggle = 1) {  // ❌ Bug: Should be '==', not '='
            GPIOD->ODR ^= (1 << 12); // Toggle LED
            toggle = 0;
        } else {
            toggle = 1;
        }
        delay(1000000);
    }
}

Step 2: Compile with Debug Symbols

When compiling, include the -g flag (to generate debug symbols) and disable optimization (-O0) so GDB matches your source lines correctly.

Example Makefile snippet:

CFLAGS = -mcpu=cortex-m4 -mthumb -O0 -g
LDFLAGS = -Tstm32f4.ld

all:
    arm-none-eabi-gcc $(CFLAGS) main.c -o main.elf $(LDFLAGS)

This produces a main.elf file — that’s what you’ll use with GDB.

Step 3: Flash the Firmware

Flash your .elf file to the STM32 board (using OpenOCD or ST-Link Utility). Example command:

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program main.elf verify reset exit"

Step 4: Start the GDB Server

Now run OpenOCD to start the GDB server:

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg

You should see something like:

Info : Listening on port 3333 for gdb connections

That means OpenOCD is ready for Debugging STM32 with GDB.

Step 5: Connect with GDB

In another terminal, run:

arm-none-eabi-gdb main.elf

Then connect to the running GDB server:

(gdb) target remote localhost:3333

You are now connected to your STM32 MCU and ready for Debugging STM32 with GDB.

Step 6: Start Debugging Step-by-Step

Here’s how we can debug the bug in the LED code:

1. Halt the MCU

(gdb) monitor reset halt

2. Set a Breakpoint at main

(gdb) break main

3. Run the Program

(gdb) continue

Once the breakpoint hits, you’ll be inside main().

4. Step Through Code

(gdb) next
(gdb) next
(gdb) next

You’ll notice execution enters the loop with the line:

if (toggle = 1)

5. Inspect Variable Value

(gdb) print toggle

You’ll see:

$1 = 1

No matter how many times you loop, toggle is always 1. That’s the bug!
We used a single equals (=) for assignment instead of double equals (==) for comparison.

Step 7: Fix the Bug

Change:

if (toggle = 1)

To:

if (toggle == 1)

Rebuild the firmware:

arm-none-eabi-gcc -O0 -g main.c -o main.elf -Tstm32f4.ld

Reflash:

openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program main.elf verify reset exit"

Reconnect GDB and test again:

arm-none-eabi-gdb main.elf
(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) break main
(gdb) continue

Now when you step through the loop and print the variable:

(gdb) print toggle

You’ll see it alternates between 0 and 1 correctly — your LED should now blink as expected.

Step 8: Explore More Debugging Commands

Here are more GDB commands you’ll use often when Debugging STM32 with GDB:

CommandDescription
info breakpointsShow all breakpoints
deleteRemove breakpoints
stepiStep one instruction
info registersShow all CPU registers
x/10xw 0x20000000Examine 10 words from RAM address
btShow backtrace
display varContinuously show variable each step
quitExit GDB

These tools give you complete visibility inside your STM32 microcontroller.

Step 9: Debugging STM32 with GDB Like a Pro

Once you’re confident with simple programs, you can start debugging:

  • FreeRTOS tasks (by switching thread contexts)
  • Interrupt handlers
  • Peripheral registers
  • Startup code and exceptions

With Debugging STM32 with GDB, you’re not limited to LEDs or simple loops — you can see how the system runs at every level.

Types of interview questions you can expect with examples and what they’re really checking for

1. Conceptual Questions about GDB

These test whether you truly understand how GDB works and how to use it effectively.

Examples:

  • What is GDB, and how is it used in embedded development?
  • Explain how GDB communicates with STM32 hardware.
  • What is the difference between local and remote debugging?
  • How does OpenOCD fit into debugging STM32 with GDB?
  • How can you debug a program running from flash vs RAM?

What they test:
Your understanding of GDB fundamentals and STM32 architecture integration.

2. Practical Debugging Scenario Questions

These check your real-world problem-solving and step-by-step approach.

Examples:

  • You flashed firmware to STM32, but it’s not running. How would you debug it with GDB?
  • The LED blink program doesn’t toggle correctly. What steps would you take in GDB to find the bug?
  • How can you check the value of a variable in memory using GDB?
  • If your STM32 is stuck in a hard fault handler, how will you find the cause using GDB?

What they test:
Your ability to think like a debugger, inspect memory, use breakpoints, and step through code.

3. Commands and Syntax-Based Questions

These focus on your familiarity with essential GDB commands.

Examples:

  • What does the step command do in GDB?
  • What is the difference between next and step?
  • How do you set and delete breakpoints?
  • What command shows register contents?
  • How do you load symbols and start remote debugging?

What they test:
Your hands-on proficiency and whether you’ve really used GDB in practice.

4. Advanced Debugging Questions

These are common in mid to senior-level embedded interviews.

Examples:

  • How do you debug startup code or initialization routines in STM32?
  • What are watchpoints, and when would you use them?
  • How can you inspect peripheral registers using GDB?
  • How do you use .gdbinit for automation?
  • How can you view disassembly during debugging?

What they test:
Your depth of experience and ability to debug low-level embedded code.

5. Integration and Toolchain Questions

These focus on your ecosystem understanding — how GDB interacts with build systems and hardware tools.

Examples:

  • What is the role of ST-Link or J-Link in debugging STM32 with GDB?
  • How is GDB connected to OpenOCD?
  • What’s the purpose of the .elf file in debugging?
  • How do you debug using VS Code or Eclipse with GDB backend?

What they test:
Whether you know the full toolchain flow — from compiling to flashing and debugging.

6. Behavioral / Troubleshooting Questions

These test how you approach problems under pressure.

Examples:

  • Tell me about a time you fixed a bug using GDB.
  • How do you handle cases when GDB shows “Target not responding”?
  • How do you isolate a bug in hardware vs software?
  • If you can’t reproduce a bug consistently, what would you do?

What they test:
Your debugging mindset, patience, and systematic thinking.

7. Cross-Domain Embedded Questions

Because STM32 debugging overlaps with firmware concepts.

Examples:

  • What happens when the MCU is in sleep mode — how would you debug it?
  • Can you explain how interrupts affect debugging?
  • How do you inspect a stack overflow using GDB?
  • What’s the significance of vector table and reset handler?

What they test:
Your firmware architecture knowledge beyond just tool usage.

Leave a Comment