kgdb+gdb 环境搭建

2025-03-20 214 0

步骤一

在运行驱动的目标机 ubuntu 系统中,新建目录用于下载内核代码 使用命令

apt source linux-image-unsigned-$(uname -r)

下载内核 进入下载好的内核目录,使用

make menuconfig

编译配置文件 .config 确保

  • CONFIG_KGDB=y:支持内核调试。
  • CONFIG_KGDB_SERIAL_CONSOLE=y:支持串口调试。
  • CONFIG_DEBUG_INFO=y:生成调试符号。
  • CONFIG_MODULE_DEBUG=y:支持模块调试。
  • CONFIG_MAGIC_SYSRQ=y:支持 SysRq。

编译内核

make -j 32
make INSTALL_MOD_STRIP=1modules_install
make install

然后修改grub,是能kgdb串口链接 编辑 `/etc/default/grub,在 GRUB_CMDLINE_LINUX_DEFAULT 中添加以下参数:

console=ttyS0,115200,kgdboc=ttyS0,115200 kgdbwait

使用update-grub 跟新grub,然后重启系统,关于ttyS0 可以在命令行通过查看。

dmesg | grep tty

步骤二

使用串口将目标机与进行调试的调试机链接,在调试机器中,使用 screen /dev/ttyUSB0 115200 链接目标机器,出现kdb>,说明串口链接成功,输入 go 使得目标机退出kgdbwait,正常启动。 启动后,在 kernel/kgdb/agent-proxy.git - agent-proxy for kgdb 下载 agent-proxy 工具,下载好后通过 make 编译,编译完成后拷贝agent-proxy/user/local/bin 下一份,使其加入到环境变量。 然后新开终端,输入

agent-proxy 5550^5551 0 /dev/ttyUSB0,115200

这里使用刚刚安装的软件将ttyUSB0这个端口复用为两个 telnet端口,这个窗口不能关闭。 再新开一个终端,输入

telnet localhost 5550

用来链接目标机,出现 Escape caharactor is '^]'. 说明链接成功,回车会进入目标机的 shell 界面,然后将之前编译出来的vmlinux,以及要调试的驱动 test.ko 拷贝到调试机器的同一目录,通过

cat /sys/module/module_name/sections/.text

查看驱动的链接位置,然后在链接目标机的串口窗口输入

echo g > /proc/sysrq-trigger

使其进入kdb界面,在kdb界面输入

kgdb

使其进去kgdb的远程链接 然后在调试机的新窗口使用gdb 调试拷贝来的vmlinux

gdb vmlinux

进入gdb界面后,使用

target remote localhost:5551

链接调试机器,然后通过

add-symbol-file test.ko 0xffffffffa022a000

添加驱动的调试信息,然后创建驱动的断点,比如open函数,断点完成后输入c ,使得目标机器正常运行,然后再链接目标机的窗口运行用户端程序,使其触发到断点的地方,就可以正常调试了。 vmlinux合驱动的目录在调试机和目标机的位置可以任意放置,但是驱动源码的位置两边的目录结构必须一致。

动态驱动的部分调试

ko 添加gdb 的symbol信

make clean; make COPTS=-g CFLAGS_MODULE=-Og

添加symbol信息 add-symbol-file /xx/xx/xx.lib(info sharelib 下的首列地址) 查看加载后地址

cat /sys/module/module_name/sections/.text
0xffffffffa022a000
cat /sys/module/module_name/sections/.data
0xffffffffa026e000
cat /sys/module/module_name/sections/.bss
0xffffffffa0273d40

启动调试

(gdb) add-symbol-file test.ko 0xffffffffa022a000 -s .data 0xffffffffa026e000 -s .bss 0xffffffffa0273d40
add symbol table from file "test.ko" at
    .text_addr = 0xffffffffa001b040
    .data_addr = 0xffffffffa026e000
    .bss_addr = 0xffffffffa0273d40
(y or n) y
Reading symbols from test.ko...
(gdb) 

动态库有分离dbg symbol信息的添加symbol信息。

info share xxx.so
add-symbol-file path(dbg symbol文件路径) 0x0xx(info首列地址)
bt

gdb 查看所有线程的所有线程中打印堆栈追踪信息 thread apply all bt

gdb 常用方法

命令 含义
dri path gdb 添加源码方法,如 dir /home/mas/mpv
info sharedlib 查看调用的动态库
layout 用于分割窗口,可以一边查看代码,一边测试
layout src 显示源代码窗口
layout asm 显示反汇编窗口
layout regs 显示源代码/反汇编和CPU寄存器窗口
layout split 显示源代码和反汇编窗口
Ctrl + L 刷新窗口
Ctrl + x,再按1 单窗口模式,显示一个窗口
Ctrl + x,再按2 双窗口模式,显示两个窗口
Ctrl + x,再按a 回到传统模式,即退出layout,回到执行layout之前的调试窗口
reverse-step 反向运行程序到上一次被执行的源代码行
return nn 退出函数(返回值)
jump +n(行号) 跳过函数,跳转到n 行执行,不会停止,需要打断点停止
until X 执行代码并在第 X 行停止
set var 变量=值 设置变量
run(简写r) 运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令
continue(简写c) 继续执行,到下一个断点处(或运行结束)
next(简写n) 单步跟踪程序,当遇到函数调用时,直接调用,不进入此函数体
step(简写s) 单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的
until 运行程序直到退出循环体
until+行号 运行至某行
finish 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息
call 函数(参数) 调用“函数”,并传递“参数”,如:call gdb_test(55)
quit 简记为 q 退出gdb
break n(简写b n) 在第n行处设置断点 ;可以带上代码路径和代码名称: b OAGUPDATE.cpp:578)
break func 在函数func()的入口处设置断点,如:break cb_button
delete 断点号n 删除第n个断点
disable 断点号n 暂停第n个断点
enable 断点号n 开启第n个断点
clear 行号n 清除第n行的断点
info breakpoints(简写info b) 显示当前程序的断点设置情况
refresh 刷新界面

相关文章

发布评论