文章目录
前言
设计目标
- 在主机中可以使用gdb远程调试虚拟机。
- linux源码,编译生成的指定版本的内核文件,均在主机中。
- 将2中的文件,以共享文件夹的方式,挂载到虚拟机中。
准备工作
- 创建虚拟机:使用virt-manager管理虚拟机
- 设置虚拟机的相关选项:virt-manager设置主机和虚拟机之间文件共享
- 更换虚拟机的内核为我们需要的版本:更换虚拟机的内核版本
当完成上面三步之后,我们当前主机和虚拟机中的文件分布如下所示。
# 主机中文件夹的位置
# 主机中的linux源码文件位置
/mnt/data/linux
# 主机中linux源码编译生成的指定内核的文件位置
/mnt/data/linux_image/5.5
# 将主机中的文件夹共享到虚拟机中的位置
## 虚拟机中的linux源码文件位置
/mnt/data/linux
## 虚拟机中的经编译生成的5.5内核位置
/home/dacao/image/5.5
经过上面三步之后,距离满足设计目标,只剩下如何设置虚拟机调试。
通过虚拟机调试内核源码
我们使用Pass-through of arbitrary qemu commands,进行虚拟机的调试设置。
方式一:我们可以直接修改VM的XML文件:Debugging the Ubuntu kernel with GDB and QEMU
virsh list --all # 查看当前有哪些虚拟机
virsh edit "$GUESTNAME" # 修改需要调试的虚拟机的配置
Replacing the first line:
<domain type='kvm'>
With:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<qemu:commandline>
<qemu:arg value='-s'/>
</qemu:commandline>
方式二:我们可以借助virt-xml
命令:Easy qemu commandline passthrough with virt-xml
virt-xml bpf-fuzzer --edit --confirm --qemu-commandline="-gdb tcp::1234"
接下来便可调试虚拟机的内核了。
cd /mnt/data/linux_image/5.5
gdb -tui vmlinux
target remote localhost:1234
(gdb) c # 运行虚拟机
Continuing.
(gdb) # 进行设置断点等操作
# 对内核中指定文件的指定行下断点
(gdb) break kernel/bpf/verifier.c:1037
Breakpoint 1 at 0xffffffff811e6de0: file /mnt/data/linux/kernel/bpf/verifier.c, line 1038.
(gdb) c
Continuing.
# 在虚拟机中运行一个可以触发该行的程序
./poc
# 回到主机中,可以看到gdb显示,停在断点处
其他
如果你调试直接使用qemu启动的虚拟机,可以参考:linux内核的调试