linux-kernelgdbqemu

Debugging Linux kernel under QEMU with GDB: breakpoints are not hit


I am using Ubuntu 24.04 system under qemu-system-aarch64 +gdb-multiarch to debug the kernel. But setting breakpoint doesn't make it to stop.

System information:

Steps to reproduce:

  1. Boot the system using qemu:
    qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8" -nographic -drive if=none,file=rootfs_ext4.img,id=hd0 -device virtio-blk-device,drive=hd0 --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount -S -s
    
  2. Use gdb-multiarch to connect and debug:
    gdb-multiarch vmlinux
    (gdb) target remote localhost:1234
    Remote debugging using localhost:1234
    
    0x0000000040000000 in ?? ()
    
    (gdb) b start_kernel
    Breakpoint 1 at 0xffff2000126704ec: file init/main.c, line 538.
    (gdb) c
    Continuing.
    

I tried replacing the debugged Linux kernel with version 5.10.9, but the problem still exists. I tried replacing the gdb tool with GNU gdb (Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24)) 14.2.90.20240526-git, but the problem still exists.


Solution

  • That's because you forgot to disable KASLR. The breakpoint you place will never be hit because the symbol address you get from vmlinux does not match the real one at runtime, as the kernel image will be moved somewhere else in memory when KASLR is applied at boot, before start_kernel() is invoked. Add nokaslr to your kernel command line (the -append option of QEMU) and you will hit the breakpoint as expected.