news 2026/7/11 19:11:38

段错误?死锁?Core Dump不会用?3个GDB技巧让你调试效率翻倍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
段错误?死锁?Core Dump不会用?3个GDB技巧让你调试效率翻倍

段错误?死锁?Core Dump不会用?3个GDB技巧让你调试效率翻倍

嵌入式开发里最浪费时间的事情是什么?不是写代码,是找bug。尤其是那些"我代码逻辑没问题啊,怎么就崩了"的bug。

今天聊3个GDB实战技巧,每一个都是我在调试Linux驱动和嵌入式应用时反复用到的。不扯理论,直接上命令。


技巧一:搞定段错误——从Core Dump回溯现场

段错误是嵌入式开发者的老朋友了。指针飞了、数组越界、栈溢出,结果都是SIGSEGV。

第一步:打开Core Dump

默认系统不开core dump,先打开:

ulimit-cunlimitedecho"/tmp/core.%p.%e">/proc/sys/kernel/core_pattern

这样程序崩溃后,/tmp/core.1234.myapp就有了。

第二步:回溯现场

gdb ./myapp /tmp/core.1234.myapp(gdb)bt(gdb)bt full(gdb)info registers

bt看调用栈,bt full看每层函数的局部变量值。80%的段错误,一看到崩溃在哪个函数、传了什么参数,马上就能定位。

第三步:查看内存

有时候崩溃在memcpy里,bt看到的是libc的栈帧,没用。这时候看参数:

(gdb) frame 1 # 切到上一帧(调用memcpy的代码) (gdb) info args (gdb) p src (gdb) p dst (gdb) p/x *src@20 # 打印src指向的前20个字节

真实案例:一次调试WiFi驱动,skb->data指向了已释放的内存。运行几小时后随机崩溃。bt一看在memcpy,打印src发现地址在kmalloc-128 slab之外,一查是上层模块提前kfree_skb了。半小时定位,之前纯靠加printk搞了三天没找到。


技巧二:条件断点+自动化——调试时序问题

嵌入式里最恶心的一类bug:跑100次偶尔崩1次。条件断点就是干这个的。

条件断点

(gdb) break gpio_irq_handler if irq_num == 42 (gdb) break kmalloc if size > 4096 (gdb) break my_func if strcmp(name, "sensor0") == 0

自动打印+继续

调试中断处理或者驱动probe时,不想每次都手动敲命令:

(gdb) break device_probe (gdb) commands > printf "Probing %s\n", pdev->name > print devm_kzalloc(pdev, 0x1000) > continue > end

观察点(Watchpoint)

调试"哪个不要脸的改了我的变量":

(gdb) watch my_global_var # 写触发 (gdb) rwatch my_global_var # 读触发 (gdb) awatch my_global_var # 读写都触发

真实案例:调试一个I2C触摸屏驱动,g_touch_state总是不对。怀疑被别的模块改了但找不到。watch g_touch_state一上,断下来发现是DMA完成回调里直接写了共享内存——但锁机制没覆盖这个路径。5分钟找到,之前printk打了一百行没看出来。


技巧三:远程调试(gdbserver)——嵌入式板子的标配

嵌入式开发,程序跑在ARM/MIPS板子上,调试器在主机的x86上。用gdbserver:

板子端

# 编译带调试符号的目标程序arm-linux-gnueabihf-gcc-g-O0-omyapp myapp.c# 板子上启动gdbservergdbserver :2345 ./myapp

主机端

arm-linux-gnueabihf-gdb ./myapp(gdb)target remote192.168.1.100:2345(gdb)continue

剩下的和在本地一样,break、next、print全部操作远程板子的内存和寄存器。

小技巧:加载内核模块调试符号

调试驱动时:

# 板子上insmod mydriver.kocat/sys/module/mydriver/sections/.textcat/sys/module/mydriver/sections/.datacat/sys/module/mydriver/sections/.bss# GDB里(gdb)add-symbol-file mydriver.o 0x<.text地址>-s.data 0x<.data地址>-s.bss 0x<.bss地址>

然后就可以在驱动函数里打断点、单步调试了。比printk刷日志爽一百倍。

target remote

add-symbol-file

断点/单步

BKPT指令

主机 x86

gdbserver on ARM板

被调试进程

GDB 符号解析

内核模块符号

硬件调试寄存器


课后练习

  1. 写一个故意段错误的程序(比如解引用空指针),编译后用gdb的bt定位到具体行
  2. 用watchpoint找出"谁改了全局变量"
  3. 配置一个gdbserver+QEMU的远程调试环境,验证远程断点可用

一句话总结

三个技巧吃透了,大部分嵌入式调试场景不用再加printk重编。尤其Core Dump和远程调试,省的是实打实的编译部署时间,一次省半小时,一个月下来够你摸好几天的鱼。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 19:11:28

3天从零掌握LabelImg图像标注:免费开源工具实战完全指南

3天从零掌握LabelImg图像标注&#xff1a;免费开源工具实战完全指南 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check out …

作者头像 李华
网站建设 2026/7/11 19:11:10

让老Mac焕发新生:OpenCore Legacy Patcher的魔法升级指南

让老Mac焕发新生&#xff1a;OpenCore Legacy Patcher的魔法升级指南 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否有一台性能依然强劲的Mac&#xf…

作者头像 李华
网站建设 2026/7/11 19:10:38

K9s 与 Lens 深度对比:终端UI vs 图形界面的3大场景实测

K9s 与 Lens 深度对比&#xff1a;终端UI vs 图形界面的3大场景实测在 Kubernetes 集群管理的工具选择中&#xff0c;终端派与图形界面派的争论从未停止。作为技术决策者&#xff0c;如何在 K9s 这类终端 UI 工具和 Lens 这类图形化工具之间做出明智选择&#xff1f;本文将基于…

作者头像 李华
网站建设 2026/7/11 19:07:05

【架构实战】TiDB分布式数据库:从MySQL到NewSQL的迁移

【架构实战】TiDB分布式数据库&#xff1a;从MySQL到NewSQL的迁移 一、MySQL的尽头&#xff0c;是TiDB 2021年&#xff0c;业务量翻了5倍&#xff0c;MySQL分库分表也扛不住了。 当时的技术债&#xff1a; 16个MySQL库&#xff0c;128张分表&#xff0c;运维成本爆炸DDL要选窗口…

作者头像 李华
网站建设 2026/7/11 19:06:54

YimMenu:GTA V终极安全增强与游戏体验优化方案深度解析

YimMenu&#xff1a;GTA V终极安全增强与游戏体验优化方案深度解析 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/Yim…

作者头像 李华