第四章:KGDB双机调试——内核配置、连接与断点实战
KGDB,说白了就是给Linux内核装了个“调试器”。
你写用户态程序时,GDB怎么用,KGDB就怎么用。只不过这次调试的对象是内核本身。我最早接触KGDB是在一次驱动崩溃的深夜,内核直接panic,printk加了一堆还是定位不到问题。后来同事说:“试试KGDB吧。” 嗯,从那以后,我再也没怕过内核死机。
4.1 KGDB内核配置——先把门打开
要使用KGDB,第一步是让内核支持它。这需要在编译内核时打开相关选项。我个人习惯把下面这些选项全部选上:
Kernel hacking --->
[*] KGDB: kernel debugger
[*] KGDB: use kgdb over serial console
[*] KGDB: support for serial over ethernet (kgdboe)
[*] KGDB: internal test suite
[*] Compile the kernel with debug info
这里有几个关键点:
- KGDB: kernel debugger —— 总开关,必须打开
- KGDB: use kgdb over serial console —— 串口调试必备
- KGDB: support for serial over ethernet (kgdboe) —— 网络调试,速度更快
- Compile the kernel with debug info —— 没有调试符号,你断点都打不了
4.2 串口KGDB连接——最稳的方式
串口调试虽然慢,但胜在稳定。我调试早期启动阶段的代码时,网络还没起来,只能用串口。
配置方法很简单,在bootargs里加上:
kgdboc=ttyS0,115200 kgdbwait
解释一下:
kgdboc—— KGDB Over Console,指定串口设备和波特率kgdbwait—— 内核启动时等待调试器连接
目标机启动后,会停在:
Waiting for connection from remote gdb...
这时候,在主机上启动GDB:
gdb vmlinux
(gdb) target remote /dev/ttyUSB0
连接成功后,你就可以看到熟悉的GDB提示符了。
4.3 网络KGDB连接——快,但需要小心
网络KGDB比串口快得多,适合调试大量代码的场景。配置方式:
kgdboe=eth0@192.168.1.100/,@192.168.1.200/
格式是:网卡@本机IP/,@主机IP/
主机端连接:
gdb vmlinux
(gdb) target remote udp:192.168.1.100:6443
4.4 断点与单步调试——实战技巧
连接成功后,就可以像调试普通程序一样调试内核了。但有几个地方需要特别注意:
4.4.1 设置断点
(gdb) break do_fork
(gdb) break __do_softirq
(gdb) break my_driver_probe
断点可以打在函数入口,也可以打在具体行号:
(gdb) break drivers/net/phy/phy.c:456
4.4.2 单步执行
(gdb) step # 进入函数内部
(gdb) next # 跳过函数调用
(gdb) finish # 执行完当前函数并返回
这里有个坑:单步执行时,如果遇到中断或调度点,可能会跳到意想不到的地方。 我调试网络驱动时,单步执行到spin_lock,结果直接跳到了调度器里。嗯,这是因为内核在等待锁时发生了上下文切换。
msleep(),结果等了10秒才回来。后来我学乖了,遇到这类函数直接用next跳过,或者把断点打在函数返回处。
4.4.3 查看内核状态
(gdb) print current->pid
(gdb) print current->comm
(gdb) info registers
(gdb) bt # 查看调用栈
查看调用栈是我最常用的命令。内核崩溃时,bt能直接告诉你死在哪个函数里。
4.5 知识体系图
下面这张图总结了KGDB双机调试的核心流程:
4.6 实战经验总结
| 场景 | 推荐方式 | 注意事项 |
|---|---|---|
| 早期启动阶段调试 | 串口KGDB | 网络还没起来,只能用串口 |
| 驱动功能调试 | 网络KGDB | 速度快,适合大量单步操作 |
| 中断上下文调试 | 串口KGDB | 网络中断可能导致调试中断 |
| 性能问题定位 | 网络KGDB + 条件断点 | 避免频繁中断影响性能 |
- KGDB是内核调试的“最后手段”,当printk不够用时,用它
- 串口稳但慢,网络快但不稳,根据场景选择
- 单步执行时注意避开调度点和延时函数
- 调试信息必须打开,否则断点打不上去
说实话,KGDB用熟了之后,你会发现内核调试其实没那么可怕。我见过很多工程师一遇到内核崩溃就慌了,其实只要把KGDB搭好,一步步跟进去,问题总能找到。
嗯,这一章的内容就到这里。记住,调试工具只是手段,真正重要的是你对内核代码的理解。工具用得再好,看不懂代码也是白搭。
公众号:蓝海资料掘金营,微信deep3321