Kgdb调试linux kernel module

本文详细介绍了使用kgdb进行Linux内核模块调试的方法。包括如何设置调试参数、连接开发机与目标机、加载符号文件及设置断点等关键步骤。

声明:

在注明出处的条件下可以随意应用(blog.youkuaiyun.com/innotech)。

 

 

上一篇文章(kgdb vmware设置)已经说了如何在机器上面通过虚拟机设置两个机器进行kgdb调试。在实现内核可以调试的情况下。我们下面将讲解有关module的调试方法。

 

其实module的调试方法很简单。先来说明一些问题。

系统启动时的参数如ro kgdb=ttyS*,115200 kgdboc=ttyS*,115200 kgdbwait.

这些参数都可以在系统启动后传递给模块如echo kgdboc=ttyS*,115200>/sys/module/kgdboc/parameter即可设置串口参数。echo g>/proc/sysrq-tirgger即可打开kgdb调试状态。所以说这些参数不一定要在启动是传入。并且ro是readonly的意思,如果要设置断点的话。就不能有ro参数了。

 

我们设置参数如kgdb=ttyS*,115200。进入系统。

 

在develop机器上我们输入gdb vmlinux。系统将会加载vmlinux的信息。


在target机器上我们输入echo g>/proc/sysrc-trigger[enter]。此时系统处于殭死状态。


develop)(gdb)target remote /dev/ttyS*[enter]

这个时候两台机器就会连接在一起了。即可进行调试。

develop)(gdb)c[enter]

target机器将会继续执行,我们这个时候就可以加载模块了。

target)#insmod <module name>

target)#cat /sys/modules/chardev/section/.text[enter]

target)#cat /sys/modules/chardev/section/.bss[enter]

target)#cat /sys/modules/chardev/section/.data[enter]

将会分别的到.text .bss .data的具体加载位置,为0x开头

得到位置以后我们就可以在develop机器上面调试了。中断target机器。

 

develop机器上gdb将会处于等待输入状态。这个时候我们将要加载模块的地址信息用add-symbol-file。我们将输入如下

add-symbol-file <module name> ADDR -s .data ADDR -s .bss ADDR

第一个ADDR为.text段的地址,后面两个的顺序无关。

加载成功以后会有提示。然后我们就可以设置断点了。

break function

这样断点就设置完成了。我们将要在target机器上面执行。说以让gdb continue下去。

 

这个时候target机器就属于正常操作模式了。我们将要执行相应命令来是机器可以执行到function断点出,target机器就会被中断。我们可以在develop机器上面进行调试了。

 

后记:

gdb 调试模块感觉会出现一些很怪异的问题。就是代码不断来回跳转的情况。而不是一直向下走的情况,不过不影响调试。只是比较不爽而已。

 

可以参考我的另外一篇引用的代码,基本的char 模块代码。引用自the linux kernel module programming guaid.这是一本非常适合初学者的指导,可以参考。代码是经过了一定的修改,原文的代码实在2.6.10内核上面跑的。我的机器内核为2.6.32.且改为module_init(function); module_exit(function);更近进新内核模块的代码风格。

 

我将要做的是调试无线网卡驱动的模块。不过现在不知的在哪里设置断点。这个比较尴尬啊。


<think>嗯,用户提到在Linux4.15内核中使用kgdb调试时单步执行会卡住,需要解决方案。首先,我得回忆一下kgdb的基本工作原理。kgdb通过串口或网络与主机上的gdb通信,允许开发者像调试普通程序一样调试内核。单步执行卡住可能有很多原因,比如硬件问题、配置错误、内核编译选项不正确,或者kgdb与内核版本的兼容性问题。 首先,用户的内核版本是4.15,这个版本相对较老,可能和某些kgdb的补丁或配置有冲突。我需要确认内核编译时是否启用了正确的调试选项。比如CONFIG_KGDB、CONFIG_KGDB_SERIAL_CONSOLE这些选项是否打开。另外,CONFIG_FRAME_POINTER对于栈回溯很重要,如果没有启用,单步调试时可能会出问题。接下来,检查串口配置是否正确。kgdboc需要通过命令行参数指定正确的串口设备,比如kgdboc=ttyS0,115200。如果波特率不匹配,或者串口设备名错误,通信就会失败,导致gdb无法接收响应,看起来像是卡住。还要确保在启动参数中添加了kgdbwait,这样内核启动时会等待gdb连接。 然后想到硬件问题,比如串口线接触不良或者波特率不稳定,可能导致数据传输错误。建议用户更换线缆或尝试不同的波特率。另外,某些处理器架构在单步执行时需要特定的支持,比如ARM的硬件单步功能是否启用,或者是否存在内核配置中的相关选项。还有可能是内核代码本身的问题,比如在单步执行时触发了异常或死锁。查看dmesg日志是否有相关错误信息,或者在内核配置中启用更多的调试选项,比如CONFIG_DEBUG_KERNEL、CONFIG_DEBUG_INFO等,这些能提供更详细的调试信息。另外,kgdb和gdb的版本兼容性也很重要。用户是否使用了支持Linux4.15内核的gdb版本?可能需要升级或降级gdb试试。还有,编译内核时是否包含了调试符号(vmlinux文件),如果缺少符号信息,gdb无法正确解析代码位置,导致单步失效。 还有一种情况是,在单步执行某些内核代码路径时,可能会触发中断或调度,导致kgdb无法正确处理。这时候需要检查是否在中断上下文中执行,或者是否有锁未被释放。这种情况下,可能需要在内核配置中禁用某些优化,比如关闭CONFIG_PREEMPT,或者调整调度相关的选项。最后,参考之前用户提供的引用,特别是关于kgdboc的配置步骤,确保用户是按照正确流程设置的。比如,在目标机启动时正确加载kgdboc模块,主机gdb连接时使用正确的vmlinux文件和架构对应的gdb工具链(如arm-none-linux-gnueabi-gdb)。 总结下来,解决方案需要分步骤检查配置、硬件、内核编译选项、gdb版本以及可能的代码问题。可能需要用户逐一排查,提供更多日志信息才能进一步定位问题。</think>### 分步解决方案:Linux 4.15内核中KGDB单步调试卡住的排查与修复 #### 1. **确认内核编译配置** - **关键选项检查**: - 确保`CONFIG_KGDB=y`(启用KGDB核心功能) - `CONFIG_KGDB_SERIAL_CONSOLE=y`(串口通信支持) - `CONFIG_FRAME_POINTER=y`(栈回溯依赖项) - `CONFIG_DEBUG_INFO=y`(生成调试符号)[^2] - **验证方法**: ```bash grep -E "CONFIG_KGDB|CONFIG_KGDB_SERIAL_CONSOLE|CONFIG_FRAME_POINTER" /boot/config-$(uname -r) ``` #### 2. **检查串口配置与硬件连接** - **目标机启动参数**: ```bash # 在GRUB配置中添加(示例为ttyS0,波特率115200) kgdboc=ttyS0,115200 kgdbwait ``` - **硬件排查**: - 更换串口线或USB转串口适配器 - 使用示波器检测波特率稳定性(或尝试降低到`9600`) #### 3. **GDB调试流程验证** - **主机端操作**: ```bash # 使用交叉编译的GDB(如arm-none-linux-gnueabi-gdb) arm-none-linux-gnueabi-gdb vmlinux (gdb) target remote /dev/ttyUSB0 # 连接目标机串口 (gdb) continue # 触发单步调试 ``` - **常见错误处理**: - 若出现`Remote 'g' packet reply is too long`,升级GDB版本或使用`set architecture armv7`手动指定架构[^3] #### 4. **内核代码路径排查** - **单步卡住场景分析**: - 在中断处理函数中单步时,需确认`CONFIG_KGDB_LOW_LEVEL_TRAP=y`(允许调试中断上下文) - 避免在`spin_lock`保护的临界区内单步(可能导致死锁) - **调试日志提取**: ```bash dmesg | grep -i kgdb # 检查KGDB初始化日志 ``` #### 5. **内核补丁与版本兼容性** - **已知问题修复**: - Linux 4.15早期版本存在KGDB与某些CPU架构的兼容性问题,建议升级到`4.15.18`以上 - 应用官方KGDB补丁(参考[KGDB官方文档](https://www.kernel.org/doc/html/v4.15/dev-tools/kgdb.html)) #### 6. **替代调试方案** - **临时替代方法**: ```bash # 在卡住位置插入printk定位问题 echo 'module xxx +p' > /sys/kernel/debug/dynamic_debug/control ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值