日常开发中,难免会遇到内核崩溃的情况,在这个时候,除了通过崩溃日志获取信息外,通过调试工具来获取内核状态信息也是非常重要的一步。
KGDB是内核调试中使用到的核心,通过KGDB,内核可以通过调整参数来将日志输出重定向到串口上,且通过串口/网络接口来对内核进行调试。
考虑到现在机器上已经很难看到物理串口,这里仅已虚拟机为例,介绍如何通过串口进行基础调试。
调试环境准备
首先需要在虚拟机上配置串口,VirtualBox的串口配置如下:
一般来说需要配置两个串口,串口1作为日志输出,绑定到host上的/tmp/vblog文件上。串口2作为gdb的通信端口,绑定到主机的管道/tmp/vbdebug上。
这时候,Virtualbox会为guest系统准备好两个虚拟的串口设备。
此外,还需要这host上配置一下串口转发,通过socat将文件管道模拟成为host上的一个pty设备:
socat -d -d /tmp/vbdebug PTY:
内核参数配置
内核中,和串口调试相关的几个参数如下:
nokaslr
关闭 kernel address space layout randomization(kaslr), kaslr是为了防止黑客猜测内核函数地址而使用的技术,这个技术会对调试造成干扰,需要进行关闭。
kgdboc=ttyS0,115200
设置kgdb通信接口, ttyS1代表第一个串口
kgdbwait
使kgdb进入等待模式,配置这个会使得内核在kgdb准备好后,不会继续执行,而是等待串口发送过来的命令后在进行动作,可以方便gdb进行设置断点等行为。
console=ttyS1
console=tty0
将console输出重定向到串口设备ttyS1和tty0,ttyS1一般代表第一个串口设备,tty0一般代表第一个终端。
ignore_loglevel
忽略日志级别
GDB配置
配置好内核参数后,可以直接启动内核,内核会在kgdb初始化后进行等待。这时我们可以来配置gdb调试环境,首先安装内核对应的调试包。安装好的内核调试文件在如下位置:
/usr/lib/debug/lib/modules/4.15.18/vmlinux
启动gdb
gdb /usr/lib/debug/lib/modules/4.15.18/vmlinux
开始远程调试
# /dev/pts/5 是socat创建的pts设备,以实际设备路径为准
target remote /dev/pts/5
这时候,已经可以像调试一个正常的本地程序一样来调试内核了。