Table of Contents

QEMU GDB Debugging

QEMU can expose a GDB remote-debugging stub that lets GDB attach to code running inside the emulated machine—kernel, bootloader, firmware—and step through it as if it were a local process. The standard way to debug early boot without a JTAG probe.

qemu-system-arm -M versatilepb -kernel zImage -s -S -nographic

-s opens a GDB stub on localhost:1234; -S freezes the CPU at startup (waits for GDB to attach before running). In another terminal:

gdb zImage
(gdb) target remote localhost:1234
(gdb) continue
(gdb) break main
(gdb) continue

After target remote, GDB connects to QEMU. continue resumes the frozen CPU. Set breakpoints as usual—GDB will pause when they hit.

Omit -S to let the kernel boot while GDB is attaching:

qemu-system-arm -M versatilepb -kernel zImage -s -nographic
# Then quickly in another terminal:
gdb zImage
(gdb) target remote localhost:1234
(gdb) <breakpoint already hit or catch next>

This is useful when boot is fast and you want to start debugging mid-boot.

Without -s, QEMU runs normally (no GDB stub). The stub adds negligible overhead—you can run with -s all the time and attach GDB only when needed.

GDB debugging of kernels or bootloaders is more reliable than printk or serial-port debugging. You see the actual execution, register state, memory contents, and can inspect the call stack instantly. Invaluable for debugging hardware initialization or boot-time crashes.

Remote debugging over the network: -gdb tcp::1234 instead of -s (default localhost), then target remote host:1234 from GDB.