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:
- Visibility: You can see exactly what the CPU is executing and what’s stored in registers or RAM.
- Control: You can stop, continue, or step through your program at will.
- Efficiency: It saves you hours of trial and error.
- Reliability: You catch logic errors early before they become hidden hardware issues.
- 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:
- STM32 Microcontroller Board
Any STM32 board will do — for example, STM32F4, STM32F1, STM32F7, etc. - Debugger/Programmer
A ST-LINK or J-Link device is required to connect your computer to the board via the SWD or JTAG interface. - Toolchain with GDB Support
You’ll needarm-none-eabi-gdb, which is part of the GNU Arm Embedded Toolchain. - GDB Server
This acts as the bridge between your board and GDB. You can use:- OpenOCD (Open On-Chip Debugger)
- ST-LINK GDB Server
- Firmware with Debug Symbols
Always compile your code with the-gflag 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.
| Purpose | GDB Command |
|---|---|
| Stop the target | monitor reset halt |
| Set a breakpoint | break main |
| Run program | continue |
| Step into a function | step |
| Step over a line | next |
| View variables | print variable_name |
| View registers | info registers |
| Examine memory | x /x address |
| Backtrace call stack | bt |
| Watch variable | watch variable_name |
| Remove all breakpoints | delete |
| Exit GDB | quit |
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:
- Your firmware runs on the STM32.
- OpenOCD or ST-LINK server talks to the hardware over SWD or JTAG.
- GDB communicates with the server over TCP (usually port 3333).
- 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.
- Set a breakpoint at
MX_TIM2_Init(). - Run the program:
(gdb) continue - When it hits the breakpoint, step through the function using
next. - Print register values:
(gdb) print htim2.Instance->CR1 - If CR1 doesn’t show the expected configuration, you’ve found the bug.
- 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
- Use Unoptimized Builds First
Start with-O0for better visibility, then switch to optimized builds later. - Understand Your Memory Map
Know which addresses belong to flash, SRAM, and peripherals. - 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. - Keep Sessions Short
Long debug sessions can hang the board. Regularly reset the MCU. - Learn Hot Commands
Memorize 10–15 essential commands. It saves tons of time. - 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:
| Command | Description |
|---|---|
info breakpoints | Show all breakpoints |
delete | Remove breakpoints |
stepi | Step one instruction |
info registers | Show all CPU registers |
x/10xw 0x20000000 | Examine 10 words from RAM address |
bt | Show backtrace |
display var | Continuously show variable each step |
quit | Exit 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
stepcommand do in GDB? - What is the difference between
nextandstep? - 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
.gdbinitfor 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
.elffile 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.
Mr. Raj Kumar is a highly experienced Technical Content Engineer with 7 years of dedicated expertise in the intricate field of embedded systems. At Embedded Prep, Raj is at the forefront of creating and curating high-quality technical content designed to educate and empower aspiring and seasoned professionals in the embedded domain.
Throughout his career, Raj has honed a unique skill set that bridges the gap between deep technical understanding and effective communication. His work encompasses a wide range of educational materials, including in-depth tutorials, practical guides, course modules, and insightful articles focused on embedded hardware and software solutions. He possesses a strong grasp of embedded architectures, microcontrollers, real-time operating systems (RTOS), firmware development, and various communication protocols relevant to the embedded industry.
Raj is adept at collaborating closely with subject matter experts, engineers, and instructional designers to ensure the accuracy, completeness, and pedagogical effectiveness of the content. His meticulous attention to detail and commitment to clarity are instrumental in transforming complex embedded concepts into easily digestible and engaging learning experiences. At Embedded Prep, he plays a crucial role in building a robust knowledge base that helps learners master the complexities of embedded technologies.













