# 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. ```bash 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: ```bash 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: ```bash qemu-system-arm -M versatilepb -kernel zImage -s -nographic # Then quickly in another terminal: gdb zImage (gdb) target remote localhost:1234 (gdb) ``` 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.