kgdb在内核2.6.26中加入,用于调试内核。kdb是内建的内核调试器,由SGI开发。
两者差异是:
- 使用kgdb需要两个机器,通过网络连接,其中客户端使用gdb。而kdb可以直接在目标机器上调试。
- Kgdb支持C代码级别调试,可以识别内核数据结构,而kdb只能识别汇编级别。
这里两台机器(使用的是两台VBox的虚拟机),一个是目标机器(被调试内核的机器),另一台是开发机器(连接被调试内核的机器)。
要使用kgdb,需要重新编译下内核,先修改相关配置:
[*] Compile the kernel with debug info
[*] KGDB: kernel debugger --->
[*] KGDB_KDB: include kdb frontend for kgdb
CONFIG_DEBUG_INFO选项使得编译中生产调试信息。
CONFIG_STRICT_KERNEL_RWX选项会阻止内核的某些断点,所以禁止(4.15.15中并未看到此项)。并增加KDB。最后查看.config配置文件包含如下:
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_DEBUG_INFO=y
然后进行编译安装,make –j2 && make modules_install && make install
1. 内核参数
在内核启动参数中添加,表示启动,通过串口ttyS0来实现kgdb调试。
kgdbwait kgdboc=ttyS0,115200
kgdbwait可以让kgdb在内核启动阶段等待一个调试器链接进来,系统此刻是挂住的。
注:kgdboc表示kgdb over concole,是配置gdb和kgdb通信的首选机制。
也可以运行过程中使能或禁止命令,如下:
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
echo "" > /sys/module/kgdboc/parameters/kgdboc
使能kgdb后要禁止内核执行,执行如下,触发一个中断:
echo g > /proc/sysrq-trigger
目标机器挂住后,就是开发机器链接到目标机器上去了。下面来看下整个过程。
2. kgdb调试过程
1. 先将加目标机器编译生成的linux复制到开发机器上。
2. 在目标机器上添加启动参数:kgdbwait kgdboc=ttyS0,115200
3. 然后关闭机器,设置串口的端口,设置虚拟使能端口,如下,然后启动目标机器,机器将会挂住在启动阶段。。接着在开发机器上设置端口如下,最后启动开发机器:。
4. 在开发机器进行调试#gdb ./vmlinux
这个vmlinux 就是从目标机器复制过来的。
执行如下:
# gdb ./vmlinux
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./vmlinux...done.
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
0xffffffff98145410 in ?? ()
(gdb)
这样连上了目标主机了。
输入continue命令,继续内核执行。
收工。
关于如何调试内核及内核模块,请看下回分析。
3. 参考
http://oliveryang.net/2015/08/using-kgdb-debug-linux-kernel-1/
https://www.kernel.org/doc/html/v4.15/dev-tools/kgdb.html