DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

背景

在开发项目的一个feature时,发现有一个线程hang住,一直无法向元数据管理模块发送心跳,导致线程所在的机器被drop掉,组里的一个同学使用gdb找到了hang住的原因,于是自己也决定学一下这种方法。

测试程序

启动两个线程,竞争互斥锁,其中一个线程拿到锁之后不释放,两个线程因为死锁必然会卡住,利用gdb找到每个线程hang住的位置。 image.png

步骤

  1. 为了生成调试信息,编译的时候加上-g选项。 image.png

  2. 后台启动main程序,查看main进程的进程id,779131。 image.png

  3. 查看进程内的所有线程。779131是main线程id(也是进程id),779132和779133是main线程启动的两个线程id,就是代码中的thread1和thread2。 image.png

  4. 用gdb attach main调试main进程。main线程启动的两个新线程id,如下图所示。 image.png

  5. 用info threads命令查看所有线程。最前面的*号表示当前线程。 image.png

  6. 用thread n命令切换线程,用bt命令检查每个线程的栈信息。可以看到线程一直阻塞在main.cpp的第10行,而第10行正是mu.lock()加锁的行,同样的方法可以找到另一个线程阻塞的位置。 image.png

总结

  • pstree -p ${pid}可以查看进程的所有线程关系。
  • gdb attach ${pid}可以调试已经启动的进程。
  • gdb中执行info threads可以查看所有的线程信息
  • gdb中执行thread n可以切换当前线程,通过bt命令查看当前线程的栈信息。

下一步

特意阅读了下《Debugging with GDB》,书中有关多线程调试的章节还是挺多的,但是都没有结合例子说明,阅读的难度对我来说还是挺大的,只能自己google+尝试实践。

posted on   DoubleLi  阅读(949)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2018-03-14 多线程使用信号量sem_init,sem_wait,sem_post
2017-03-14 Websocket协议的学习、调研和实现
2017-03-14 HTTP协议建立连接、通讯与关闭连接全过程
2017-03-14 HTTP协议学习笔记---HTTP持久连接和如何正确地关闭HTTP连接
2017-03-14 linux route命令的使用详解
2016-03-14 WiFi基本知识 .
2013-03-14 Windows界面编程第七篇 文件拖拽(文件拖放)
点击右上角即可分享
微信分享提示