用 kGDB 调试 Linux 内核
简介
这个文档记录了用kGDB调试Linux内核的全过程,都是在前人工作基础上的一些总结。以下操作都是基于特定板子来进行,但是大部分都能应用于其他平台。
要使用KGDB来调试内核,首先需要修改config配置文件,打开相应的配置,配置内核启动参数,甚至修改串口驱动添加poll支持,然后才能通过串口远程调试内核。
配置内核
基本配置
在内核配置文件:.config中,需要打开如下选项
CONFIG_KGDB | 加入KGDB支持 |
CONFIG_KGDB_SERIAL_CONSOLE | 使KGDB通过串口与主机通信(打开这个选项,默认会打开CONFIG_CONSOLE_POLL和CONFIG_MAGIC_SYSRQ) |
CONFIG_KGDB_KDB | 加入KDB支持 |
CONFIG_DEBUG_KERNEL | 包含驱动调试信息 |
CONFIG_DEBUG_INFO | 使内核包含基本调试信息 |
CONFIG_DEBUG_RODATA=n | 关闭这个,能在只读区域设置断点 |
可选选项
CONFIG_PANIC_TIMEOUT=5
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1
CONFIG_S3C2410_WATCHDOG_ATBOOT=0
CONFIG_FRAME_POINTER -- 使KDB能够打印更多的栈信息
CONFIG_KALLSYMS -- 加入符号信息
CONFIG_KDB_KEYBOARD -- 如果是通过目标版的键盘与KDB通信,需要把这个打开,且键盘不能是USB接口
CONFIG_KGDB_TESTS
启动参数
打开相应的选项后,需要配置kernel启动参数,使KGDB和内核能够找到正确的通信接口。如果是使用串口,则需要配置如下选项:
console=ttySAC3,115200 kgdboc=ttySAC3,115200
如果需要调试内核的启动过程,则需要在kgdboc后面加入kgdbwait。
在其他板子上,若使用以太网口来和KGDB进行通信,则要把kgdboc换成kgdboe(kgdb
over ethernet))。
配置完后,就可以正常编译,然后把内核下载到目标板上面。
串口驱动修改
如果在内核启动的过程中出现如下错误提示:
kgdb: Unregistered I/O driver, debugger disabled.
则需要根据这一部分,修改串口驱动程序,若能正常进入kgdb,则忽略该节,直接进入下一节使用KGDB。
在drivers/tty/serial/kgdboc.c中的configure_kgdboc函数,会通过tty_find_polling_driver(cptr,
&tty_line)来找寻内核启动参数中指定的串口驱动。然后通过kgdboc_get_char()和kgdboc_put_char()来和主机串口正常通信。
可以看到在config配置文件的CONFIG_CONSOLE_POLL就是使能串口与kgdboc的接口。如果 tty_find_polling_driver没有找到对应的串口通信接口,则会调用kernel/debug/debug_core.c中的 kgdb_unregister_io_module进行错误处理。
有的板子的串口驱动并没有加入对kgdboc通信的支持,例如Samsung的串口驱动需要在drivers/tty/serial/samsung.c中手动添加。
添加与kgdboc通信的接口,只需添加一个发送函数和接收函数,然后在驱动操作结构体中加入对应的函数就可以了。具体的PATCH如下:
drivers/tty/serial/samsung.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index ff6a4f8..5ceb7d7 100755
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -893,7 +893,29 @@ static struct console s3c24xx_serial_console;
#define S3C24XX_SERIAL_CONSOLE NULL
#endif +#ifdef CONFIG_CONSOLE_POLL
+static void s3c24xx_serial_poll_put_char(struct uart_port *port, unsigned char c)
+{
+ while (!(rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE))
+ ;
+
+ wr_regl(port, S3C2410_UTXH, c);
+}
+
+static int s3c24xx_serial_poll_get_char(struct uart_port *port)
+{
+ while (!(rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_RXDR))
+ ;
+
+ return rd_regl(port, S3C2410_URXH);
+}
+#endif
+
static struct uart_ops s3c24xx_serial_ops = {
+#ifdef CONFIG_CONSOLE_POLL
+ .poll_get_char = s3c24xx_serial_poll_get_char,
+ .poll_put_char = s3c24xx_serial_poll_put_char,
+#endif
.pm = s3c24xx_serial_pm,
.tx_empty = s3c24xx_serial_tx_empty,
.get_mctrl = s3c24xx_serial_get_mctrl,
--
1.7.5.4
加入这个patch,重新编译内核,之后就能正常进入kgdb
gdb远程调试
如果在内核启动参数中加入了kgdbwait,则内核会在完成基本的初始化之后,停留在kgdb的调试陷阱中,等待主机的gdb的远程连接。
由于大部分的板子只有一个调试串口,所以你需要把之前与串口通信的minicom退出来,然后在内核源码的目录下,执行以下命令:
$ arm-linux-gnueabi-gcc vmlinux
(gdb) target remote /dev/ttyUSB0
(gdb) set detach-on-fork on
(gdb) b panic()
(gdb) c
当然,你也可以agent-proxy来复用一个串口,通过虚拟出两个TCP端口。这时候,gdb就需要用target
remote命令连接kgdb,例如:
(gdb) target remote localhost:5551
agent-proxy可以通过这里获取:git://git.kernel.org/pub/scm/utils/kernel/kgdb/agent-proxy.git,具体用法,请看该repo下的README。
在用gdb来调试内核的时候,由于内核在初始化的时候,会创建很多子线程。而默认gdb会接管所有的线程,如果你从一个线程切换到另外一个线程,gdb会马上把原先的线程暂停。但是这样很容易导致kernel死掉,所以需要设置一下gdb。
一般用gdb进行多线程调试,需要注意两个参数:follow-fork-mode和detach-on-fork。
detach-on-fork参数,指示GDB在fork之后是否断开(detach)某个进程的调试,或者都交由GDB控制:
set detach-on-fork [on|off]
- on: 断开调试follow-fork-mode指定的进程。
- off: gdb将控制父进程和子进程。
follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态。follow-fork-mode的用法为:
set follow-fork-mode [parent|child]
- parent: fork之后继续调试父进程,子进程不受影响。
- child: fork之后调试子进程,父进程不受影响。
REFERENCE
- gdb user
mannual: http://sourceware.org/gdb/current/onlinedocs/gdb/ - gdb
internal: http://www.sourceware.org/gdb/onlinedocs/gdbint.html - kgdb/kdb official
website: https://kgdb.wiki.kernel.org/ - kernel debug
usage: http://www.kernel.org/doc/htmldocs/kgdb.html - kdb in elinux.org: http://elinux.org/KDB
- multi-threads debug in
gdb: http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/ - KGDB.info: http://www.kgdb.info/
用 kGDB 调试 Linux 内核的更多相关文章
- VELT-0.1.5开发:使用kgdb调试Linux内核【转】
转自:http://demo.netfoucs.com/lights_joy/article/details/44106589 VELT的全称是Visual EmbedLinuxTools,它是一个与 ...
- 使用QEMU调试Linux内核代码
http://blog.chinaunix.net/uid-20729583-id-1884617.html http://www.linuxidc.com/Linux/2014-08/105510. ...
- 【转】TI-Davinci开发系列之六CCS5.2调试Linux内核
上转博文<TI-Davinci开发系列之五CCS5.2使用gdbserver远程调试应用程序> 使用CCS5.2远程调试内核时,只需导入Linux内核源码,而不需要编译内核,也就不会用到交 ...
- Gdb远程调试Linux内核遇到的Bug
知识共享许可协议本作品采用知识共享署名 4.0 国际许可协议进行许可.转载保留声明头部与原文链接https://luzeshu.com/blog/gdb-bug 本博客同步在http://www.cn ...
- 跟踪调试Linux内核的启动过程
跟踪调试Linux内核的启动过程---使用gdb 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...
- 在qemu环境中用gdb调试Linux内核
简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...
- 使用 ftrace 调试 Linux 内核【转】
转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...
- 用qemu+gdb tcp server+CDT调试linux内核启动-起步
用qemu+gdb tcp server+CDT调试linux内核启动-起步 说明: 环境信息与 用virtualbox+模拟串口+CDT调试linux内核 TCP IP协议栈-起步 提到的一样,并且 ...
- 学习构建调试Linux内核网络代码的环境MenuOS系统
构建调试Linux内核网络代码的环境MenuOS系统 一.前言 这是网络程序设计的第三次实验,主要是学习自己编译linux内核,构建一个具有简易功能的操作系统,同时在系统上面进行调试linux内核网络 ...
随机推荐
- 初次使用xUtils3
由于初学Android,之前也没接触过xUtils2.X系列,所以xUtils3.X弄了很久还是一直报空指针异常,后来看了Sample找到问题所在,现在把xUtils3.X的使用写来供像我这样的小白参 ...
- jQuery+ajax城市联动
分享一下自己最近写的城市联动.技术使用ajax+jQuery实现. 首先请看前台的javascript代码. 以下是连个实现异步加载的方法. <script type="text/ja ...
- 【转】Quartz.NET
原文链接:http://www.cnblogs.com/tommyli/archive/2009/02/09/1386644.html Quartz.NET是一个开源的作业调度框架,是OpenSymp ...
- python协程有多厉害?
爬一个××网站上的东西,测算了一下协程的速度提升到底有多大,网站链接就不放了... import requests from bs4 import BeautifulSoup as sb import ...
- python013 Python3 循环语句
Python3 循环语句本章节将为大家介绍Python循环语句的使用.Python中的循环语句有 for 和 while.Python循环语句的控制结构图如下所示: while 循环Python中wh ...
- python007 Python3 数字(Number)
var1 = 1 var2 = 10 您也可以使用del语句删除一些数字对象的引用.del语句的语法是: del var1[,var2[,var3[....,varN]]]] 您可以通过使用del语句 ...
- PTA 05-树9 Huffman Codes (30分)
题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/671 5-9 Huffman Codes (30分) In 1953, David ...
- SQL Prompt 5.1使用
SQL Prompt 5.1教程 1.下载 自行下载安装文件.本人是从http://www.cr173.com/下载的. 2.安装 安装没什么特别的,不用说了 3.注意一下破解和配置 按里面的read ...
- 安装Android SDK(东软开源镜像介绍)
启动 Android SDK Manager ,打开主界面,依次选择「Tools」.「Options...」,弹出『Android SDK Manager - Settings』窗口: 在『Andro ...
- PatentTips - Solid State Memory Wear Leveling
BACKGROUND OF THE INVENTION Solid-state memory devices encompass rewritable non-volatile memory devi ...