KGDB调试搭建使用心得


前言

  最近遇到一个棘手的问题,反复加入printk添加打印语句,重新编译内核或者模块太麻烦,想找个方法能一步步看下去,gdb是一个不错的选择,所以使用kgdb来调试开发板是个不错的选择。


一、kgdb是什么?

  kgdb是用于Linux操作系统的内核级调试器。可以通过远程调试接口连接到正在运行的内核,实时调试内核代码。

二、使用步骤

1. 配置内核KGDB

配置名称作用
CONFIG_KGDB_SERIAL_CONSOLE使KGDB通过串口与主机通信(使用串口KGDB时必须打开)
CONFIG_KGDB_KDB打开KGDB调试
CONFIG_DEBUG_INFO使内核包含基本调试信息
CONFIG_DEBUG_KERNEL包含驱动调试信息

2.启动KGDB

  启动KGDB的方式有两种:

  1. 方法1:
    主要用于调试内核初始化,在kernel的启动参数上添加kgdboc=ttyXXX,115200 kgdbwait,前者设置开发板使用的串口,后者数字设置波特率。kgdbwait这个字符串的作用就是让内核停在刚启动的地方

启动参数如何加?
  对于GRUB引导可以在grub中设置参数,如下图箭头所示的地方的末尾进行添加:
在这里插入图片描述
  另一种对于uboot启动的可以直接进uboot的命令行,在原来的bootargs环境变量里加上“kgdboc=ttyXXXX,115200 kgdbwait”

  1. 方法2:
    在系统启动后,设置进入kgdb模式
# 设置调试串口
echo "kgdboc=ttyXXX,115200" > /sys/module/kgdboc/parameters/kgdboc

# 设置魔术键,g就是进行KGDB模式
echo g > /proc/sysrq-trigger

需要注意:
  这里设置魔术键执行完后,开发板进入kgdb模块,这时开发板按任何键都不会有任何反应,内核等待接受gdb调试请求

3. 开始调试

  首先,在主机上安装gdb-multiarch

sudo apt-get install gdb-multiarch

  进入到内核源码根目录,执行

sudo gdb-multiarch vmlinux

一切正常的话,会在终端输出如下提示:

GNU gdb (Ubuntu 9.1-0kylin1) 9.1
Copyright (C) 2020 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...
warning: File "/home/xxx/kernel-5.15/scripts/gdb/vmlinux-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
	add-auto-load-safe-path /home/xxx/project_data/startkylin/gerrit-5.15/scripts/gdb/vmlinux-gdb.py
--Type <RET> for more, q to quit, c to continue without paging--
line to your configuration file "/root/.gdbinit".
To completely disable this security protection add
	set auto-load safe-path /
line to your configuration file "/root/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
	info "(gdb)Auto-loading safe path"
(gdb) 

  然后,我们需要设置目标平台,串口波特率,并且通过串口连接到开发板上的kgdb上

# 设备目标平台
set architecture aarch64
# 设置串口波特率
set serial baud 115200
# 主机通过串口连接到开发板上的kgdb
target remote /dev/ttyUSB0

  设置成功后会有如下提示:

(gdb) set architecture aarch64
The target architecture is assumed to be aarch64
(gdb) set serial baud 115200
(gdb) target remote /dev/ttyUSB0
Remote debugging using /dev/ttyUSB0
arch_kgdb_breakpoint () at ./arch/arm64/include/asm/kgdb.h:21
21		asm ("brk %0" : : "I" (KGDB_COMPILED_DBG_BRK_IMM));

  设置断点,并继续运行,并停止在断点

(gdb) b user_path_at_empty
Breakpoint 1 at 0xffffffc0082acb40: file fs/namei.c, line 2799.
(gdb) c
Continuing.
[Switching to Thread 5657]

Thread 1152 hit Breakpoint 1, user_path_at_empty (dfd=dfd@entry=-100, 
    name=name@entry=0x7299bdc630, flags=flags@entry=16384, 
    path=0xffffffc014d03df8, path@entry=0xffffffc014d03e48, empty=0xffffffc014d03df4, empty@entry=0xffffffc014d03e44)
    at fs/namei.c:2799
2799	{
(gdb) 

  如果此时,设置的断点不是系统必跑的地方,那么会发现,此时adb又可以输入命令了,可以用指令来触发断点。
  再回到gdb界面,继续使用n、s、l、p的方式去debug代码了。

最后,再贴上比较常用的gdb指令:

指令简写全称作用
rrungdb filename只是attach到一个调试文件,run启动程序
ccontinue使用continue让程序继续运行
bbreak设置断点
d xdelete x删除断点,可以通过i b获取到断点编号x
nnext单步步过,遇到函数调用会直接跳过,不会进入函数内
sstep单步步入,遇到函数调用会进入函数内部
llist查看当前执行点前后5行代码
pprint查看变量的值,得到函数执行结果
finish\直接执行完当前函数,返回调用处,并输出返回值
uutil快速执行到指定行
jump\可以跳转到指定行或函数,中间的被略过,如果指定位置没有断点,将继续执行
display xxx\监视某变量(xxx),每一步都会自动输出变量的值
d display xxxdelete display xxx移除对指定变量的监视,可以通过i display获取编号x
btbacktrace查看当前位置的调用堆栈
fframe与backtrace结合使用,切换不同堆栈
i binfo break查看断点信息
i localsinfo locals查看当前函数当前执行点的本地变量值
i argsinfo args查看当前函数的传入参数值
i displayinfo display查看当前监控那些变量

总结

  上面是个人使用kgdb时的一些心得,kgdb很方便,但有时候使用kgdb容易卡死,或者在一个函数需要很久才能返回,还是有一些缺陷。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
kgdbLinux内核中的一个调试工具,可以用来调试内核崩溃、死锁等问题。下面是kgdb的基本使用方法: 1. 安装kgdbLinux系统中,kgdb通常是作为内核的一个模块来安装的。你需要确保你的系统中已经安装了kgdb模块。如果没有安装,你可以通过以下命令安装: ``` sudo apt-get install kgdb ``` 2. 启用kgdb 为了使用kgdb,你需要在内核启动时启用kgdb。在内核启动参数中添加kgdboc选项即可。例如: ``` kernel /vmlinuz-5.4.0-42-generic root=/dev/sda1 kgdboc=ttyS0,115200 ``` 这个例子中,我们将kgdb输出到了串口ttyS0。你可以根据需要将kgdb输出到不同的设备中。 3. 连接kgdb 启动内核后,你需要通过一个调试器来连接到kgdb。常用的调试器有gdb和ddd。例如,使用gdb连接kgdb: ``` gdb vmlinux (gdb) target remote /dev/ttyS0 ``` 这个例子中,我们使用gdb连接到了kgdb输出到的串口ttyS0。 4. 调试内核 连接成功后,你就可以使用gdb或者ddd来调试内核了。例如,你可以使用gdb的break命令在某个函数入口处设置断点: ``` (gdb) break some_function ``` 然后运行内核: ``` (gdb) continue ``` 当内核执行到some_function时,kgdb会自动中断内核,并将控制权交给gdb。你可以使用gdb的各种命令来查看内核状态,例如查看寄存器、查看内存、查看函数调用堆栈等等。 5. 断开连接 当你完成调试后,可以使用gdb的detach命令断开连接: ``` (gdb) detach ``` 以上就是kgdb的基本使用方法。需要注意的是,kgdb是一个非常强大的工具,需要谨慎使用。如果你不确定如何使用kgdb,最好先阅读相关文档或者请教专业人士。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

坚持不秃0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值