调试 libvirt 启动的 VM
Lapin Gris Lv3

上篇,我们介绍了如何使用 qemu 启动内核并对其进行 debug。如今,很多云服务器都是通过 libvirt/qemu 启动的。
本文就着手介绍,如何调试由 libvirt 启动的 linux 内核。

xml 添加 -s 参数

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<qemu:commandline>
<qemu:arg value='-s'/>
</qemu:commandline>
</domain>

添加 -s 参数后,qemu 会启动 1234 端口用来监听来自 gdb 的连接。

# ss -nltp | grep 1234
LISTEN 0 1 0.0.0.0:1234 0.0.0.0:* users:(("qemu-kvm",pid=1273698,fd=107))
LISTEN 0 1 [::]:1234 [::]:* users:(("qemu-kvm",pid=1273698,fd=108))

关闭内核地址空间随机化

ASLR 是一个安全相关的特性,默认情况下,ASLR 是打开的。但是打开 ASLR 会导致我们 debug 过程中 gdb 无法命中断点。

因此,我们需要登录到 Guest 里通过向内核命令行添加 nokaslr 参数来关闭内核地址空间随机化。

grubby --update-kernel=ALL --args="nokaslr"

修改完成后,重启机器(reboot),重启后通过如下命令确认关闭成功,

cat /proc/cmdline | grep nokaslr

安装 debuginfo

假设我们的 guest 内核版本是 4.18.0-553.8.1.el8_10

下载对应的 kernel-debuginfo 和 kernel-debuginfo-common 包, 并安装,

yum localinstall kernel-debuginfo-4.18.0-553.8.1.el8_10.x86_64.rpm kernel-debuginfo-common-x86_64-4.18.0-553.8.1.el8_10.x86_64.rpm

连接到 Guest

安装完 debuginfo 后,通过 gdb 连接到 Guest 即可开始 debug,

# gdb /usr/lib/debug/lib/modules/4.18.0-553.8.1.el8_10.x86_64/vmlinux

(gdb) target remote :1234
(gdb) hbreak pick_next_task_fair
(gdb) c

set breakpoint at pick_next_task_fair