无法让 gdb 在 Qemu 下的 Linux 内核 运行 中的断点处停止

Can't get gdb to stop at breakpoint in Linux kernel running under Qemu

已编译 linux 5.5.5 内核,使用 make menuconfig 添加选项 CONFIG_GDB_SCRIPTS 并关闭选项 CONFIG_DEBUG_INFO_REDUCED 。 运行 qemu

qemu-system-x86_64 \
    -kernel arch/x86/boot/bzImage \
    -append "root=/dev/sda1" \
    -device virtio-scsi-pci,id=scsi0 \
  -drive file=../../zso2020_cow.qcow2,if=none,id=drive0 \
  -device scsi-hd,bus=scsi0.0,drive=drive0 \
  -enable-kvm \
  -smp 1 \
  -net nic,model=virtio -net user \
  -net user,hostfwd=tcp::2222-:22 \
  -m 1G -balloon virtio \
  -fsdev local,id=hshare,path=$(pwd),security_model=none -device virtio-9p-pci,fsdev=hshare,mount_tag=hshare \
  -chardev stdio,id=cons,signal=off -device virtio-serial-pci -device virtconsole,chardev=cons \
  -soundhw hda \
  -usb -device usb-mouse \
  -gdb tcp::23308 \
  -display none \
  -S

Qemu 使用编译内核运行,我在源代码中使用 kprint 检查过。 然后我跑了

gdb \
    -ex "add-auto-load-safe-path $(pwd)" \
    -ex "file vmlinux" \
    -ex 'target remote localhost:23308' \
    -ex 'break start_kernel' \
    -ex 'continue'

(两个脚本都是从编译内核的目录运行的)

Qemu进入用户登录,gdb输出(等待断点)

GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from vmlinux...done.
Remote debugging using localhost:23308
0x000000000000fff0 in exception_stacks ()
Breakpoint 1 at 0xffffffff8271db30: file init/main.c, line 577.
Continuing.

我也试过了

在任何情况下,gdb 都不会在断点处停止。

如何使用 gdb 正确连接到内核,在哪里查找错误?

问题的解决方案是添加 nokaslr 选项并使用 hbreak。这意味着替换

-append "root=/dev/sda1"

`-附加 "root=/dev/sda1 nokaslr"

break start_kernel

hbreak start_kernel

然后 gdb 正确捕获内核断点。