KGDB-linux内核调试环境的创建
前段时间由于刚开始接触linux,一切处在摸索的状态,为建立一个KGDB的内核调
试环境
, 查了很多资料费了很多周折,后来总算是完成了。但当时没来得及总结,今天乘着有
时间,写个简单的总结,希望能对那些需要构建kgdb环境的linux朋友有些许帮助.
KGDB是个源代码级的内核调试环境,换句话说,它其实就是gdb远端调试.gdb调试
应用程
序,仅需在一台机子上就可实现,但要利用gdb调试内核,则需要两台机子,通过串口相连,
一台机子称为开发主机(Host),另外一台机子称为目标机(target),两台机子预先装有Re
d Hat linux 7.3系统.
Host运行gdb调试程序,target运行待调试的系统内核,Host的gdb程序通过串口线对目标
机运行的内核进行调试和控制.gdb调试程序是一个源代码级的调试,可对待调试的操作系
统内核进行设立断点和单步执行,由此可清楚的了解内核的工作过程以及应用程序如何由
系统内核实现.
一. 硬件配置工作:
KGDB是通过串口实现开发主机Host对目标机的控制过程,这里首先需要准备一条
串口线
将两台机子连起来.我的串口线是用普通网线将两个9口公口串口线连接起来,只用到了三
根线,将串口的管脚2,3,5连起来.这里连的时候,需要注意两个串口管脚的连接:5-5,2-3
,3-2.即将2,3对调.因为9口串口中2为发送数据,3为接收数据,5为接地.
测试串口工作是否正常:(windows下可直接利用超级终端就可判断),但在linux下
有所不
同.
在开发主机上:
#stty ispeed 38400 ospeed 38400 -F /dev/ttyS0 //设置串口的收发速率
#cat testfile.txt > /dev/ttyS0 //将文件testfile.txt内容输入到串口
ttyS0中
在目标主机上:
stty ispeed 115200 ospeed 115200 -F /dev/ttyS0 //设定串口速率
cat /dev/ttyS0 //接收从串口中收到的内
容并显示到屏幕上
若目标主机屏幕上能看到testfile.txt内容,反过来目标机发,开发机收,也显示正常,则
说明串口工作正常.
二. KGDB具体建立过程
KGDB是一个内核补丁,需要考虑版本的问题.下面我以2.4.18内核为例,具体讲一下kgdb调
试环境的建立步骤.
开发主机:
1. 下载内核源代码2.4.18并把这个文件拷贝到/usr/src/目录下,记为linux2.4.18,
为其
建立一个链接文件linux.下载kgdb内核补丁kgdb2.4.18 (kgdb补丁下载地址
b.linsyssoft.com/downloads.htm)到目录/usr/src/linux下.
2. 转到/usr/src/linux目录,执行命令$patch -p1< kgdb2.4.18给2.4.18内核打上
kgdb
内核补丁.
3. 对内核进行编译,编译内核请参考相关文章.主要是执行几个命令
a) make menuconfig(字符界面)/xconfig(图形界面),对要编译的内核选取选项,将
kern
el hacking选项下选取kernel support for GDB这个选项,对应于核心代码里面的宏就是
CONFIG_GDB.
b) 依次运行
#make dep
#make clean
#make bzImage
#make modules
#make modules_install 生成新的内核.
这里生成了两个文件:
/usr/src/linux/System.map
/usr/src/linux/arch/i386/bzImage
以及带调试信息的/usr/src/linux/vmlinux,作以后调试用.
目标主机:
将开发主机上新生成的内核文件System.map, bzImage 下载到目标机
boot目录下,改名
为Systemkgdb.map与bzImagekgdb.可用ftp文件传输实现.
修改/etc/lilo.conf配置文件,用新生成的内核启动文件
Systemkgdb.map与bzImagekg
db启动系统.
当以此内核启动目标机系统时,它会一直等待远端的主机连接,显示如下
信息:
Waiting for connection from remote gdb...,
再次转到开发主机:
进入/usr/src/linux目录下,运行
gdb ./vmlinux //含调试信息的未压缩内核
(gdb) set remotebaud 38400
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
breakpoint () at kernel/kgdb.c:1212(源代码中所在行号)
1212:atomic_set(&kgdb_setting_breakpoint, 0);
warning: shared library handler failed to enable breakpoint
(gdb)
若出现上述信息,则说明kgdb的调试环境已经建立起来了.输入命令c,则可看到目
标主机
继续启动,直至出现shell命令提示符.
至此,就可在开发主机上利用gdb命令对待调试的内核设定端点,查看内核函数调
用情况
.
三.kgdb调试示例
我编了一个简单的socket client/server程序,client运行在除开发主机与目标
机外的
另外一台机子上,同样预装有linux系统.serve程序运行在目标机上,两者进行通信,而开
发主机则对这个通信过程进行控制.
程序工作流程:server端在create,…Accept后就一直等待连接,如果有client连接过来,
server就会回馈一个信息给client,并继续等待client连接.而client一启动就会向Serv
er要求连接,然后接收信息,并在屏幕上输出这个信息后就结束.
追踪的方法是在开发主机将中断点设在sys_socketcall上,然后用step这个指令来单步跟
踪.
实现步骤:
1. 启动KGDB,在目标机开完机后,可以在Host端下,用ctrl+c让远端中断,并使Host取
得控
制权.
2. 下"break sys_socketcall"指令来设定中断点在sys_socketcall这个函数上.
3. 下"cont"释放控制权,让远端继续执行.
4. 在Target端执行Server程序,之后就可以看到控制权回到Host端,并中断在
sys_socke
tcall
5. 现在可以用"step","next"来一步步跟踪核心.
看了linux网络核心源代码可以知道,在linux下的socket通信,对socket的各种操作,包括
create,bind,connect,send,recv等都是通过sys_socketcall系统调用实现的.所以在系
统内核中的sys_socketcall系统调用上设定断点,就可跟踪到socket通信过程中所涉及到
的对核心的各种函数调用关系. 详细过程可参考【2】
总结:
内核调试工具有许多种,如printk,kdb。Printk使用起来非常烦琐,而kdb显示
的组合
码形式,看起来非常晦涩。
但kgdb内核调试,是基于源代码级的调试,可对照着linux源代码进行调试,看
起来非
常轻松。当然,要实现调试,首先要对源码有相当的了解才行,呵呵。
参考文献
【1】 KGDB quick start ,b.linsyssoft.com/quickstart.htm
【2】 追踪Linux TCP/IP 核心-使用远程除错,蔡品再,林盈达。
阅读(1112) | 评论(0) | 转发(0) |