KGDB-双物理机调试内核
KGDB-双物理机调试内核
author: Ewan
准备工作
搭建双物理机调试Linux内核环境之前,需要:
- 2台物理机,均装有Linux操作系统,下文以Host和Target区分调试机和被调试机
- 一份需要调试的Linux源码
- 一根串口转USB线
attention:本文使用Target的ttyS1,Host的ttyUSB0,波特率115200.
-
将串口转USB线的串口端连接到Target上,USB端连接到Host上
连接好之后可以在Host和Guest上都安装cutecom串口通信软件,测试Host和Guest的串口通信是否正常
cutecom安装:sudo apt-get install cutecom
测试方法为,在Host和Target上均用sudo cutecom打开cutecom,然后在Host上打开设备/dev/ttyUSB0,在Target上打开设备/dev/ttyS1,尝试互相发送数据,如果成功,说明串口连接无故障。
-
在Target上编译并安装需要调试的Linux源码,在
make menuconfig
时注意需要选择KGDB* , KGDB_SERIAL*, KGDB_USB*, DEBUG_INFO, DEBUG_INFO_DWARF4, MAGIC_SYSRQ
这些内核编译选项,我使用的5.3.8默认包含这些选项.编译安装完成后,向/etc/default/grub
中的GRUB_CMDLINE_LINUX
添加nokaslr, 以保证内核代码不会随机改变位置,然后运行sudo update-grub,将添加的信息更新到grub中,重启Target. -
完成以上工作之后,将源码目录下生成的
vmlinux
文件拷贝到Host -
在Host上下载
Agent-Proxy
并编译,然后启动Agent-Proxygit clone http://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git
cd agent-proxy;make
sudo ./agent-proxy 5550^5551 0 /dev/ttyUSB0,115200
Agent-Proxy是一款开源代理软件,能够将串口分割为多个功能,这里使用Host的5550和5551两个端口,5550用于连接Target的console, 5551用于连接Target的KGDB监听端口
开始调试
- 在Host上连接Target的console
- 在Target上进入kgdb模式
然后就可以在dmesg里看到Registered I/O driver kgdboc
,如果没看到说明哪些地方出问题了。
然后利用下面的命令将Target的运行暂停,这样就可以在host上使用gdb连接并调试。
如果想要调试系统启动早期代码,则需要在Target启动时暂停,如果有这种需求,可以在Target的启动选项中加入console=tty0 console=ttyS1,115200 kgdbwait kgdboc=ttyS1,115200
-
然后就可以在步骤1的窗口中看到类似于下面的内容:
Entering kdb (current=0xcb846c80, pid 2301) on processor 3 due to Keyboard Entry
[3]kdb>
在[3]kdb> 后输入kgdb,这之后Target就会进入等待远程gdb连接的状态。
-
在Host上新开一个Terminal窗口,进入从源码目录,输入gdb vmlinux,这里的vmlinux就是之前在Target上生成,拷贝到Host上的Linux符号文件。
该步骤的全部输入如下:
gdb vmlinux
(gdb) target remote localhost:5551
Remote debugging using localhost:5551kgdb_breakpoint () at kernel/debug/debug_core.c:1072
1072 wmb(); /* Sync point after breakpoint */
(gdb)
然后就可以快乐地使用gdb进行调试Target了。
-----update on 11.5.2020-------------------
使用上面的步骤,确实可以调试一些功能,但是最近想调试kvm的代码,发现经过上面的步骤,进入到gdb之后,无法在kvm中设置断点,例如:
此时要怎么做呢?
kvm和kvm_intel都是内核的module,vmlinux默认情况下是不加载module的符号的,需要手动加载。
- 在target上找到kvm和kvm_intel的.text段地址
我获得的target上kvm和kvm_intel两个module在内核中的.text位置分别为:
0xffffffffc0205000,0xffffffffc0335000.
- 在host上的gdb调试窗口将这两个地址的符号加载进gdb
注意这一步中,gdb vmlinux运行的目录为从target复制过来的Linux源码的目录
然后就可以在类似于handle_io的kvm代码出下断点了。
__EOF__

本文链接:https://www.cnblogs.com/haiyonghao/p/14440924.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律