用于调试多线程下程序异常入锁导致整个进程资源死锁,可通过GDB线程调试暂停点的各个线程栈情况。
(1) 使用GDB启动程序
(2)在线程死锁处停止程序$gdb TmsServer进入GDB后启动程序(gdb) r
(a)目前本程序特征是在资源死锁后不再对外部请求作出响应
发现出现不响应时首先查看是否出现核心转储,若没有则表明程序确实进入某种锁状态,按ctrl+c暂停程序
(3) 查看当前节点上线程状态
(4) 切换线程
(5) 查看线程堆栈,并查处死锁位置
(6)多切换几个线程,全面的分析死锁的原因。一般来说首先使用频率最高的锁在所有函数出口上是否已解锁。
本次分析:
分析锁之间的阻塞关系,发现阻塞recv的都是writelog,因为该锁中间有嵌套关系,而从第二组可看出最终造成死锁的是writelog锁,因此排查writelog是否有很低级错误。结果未发现。
第一次程序死锁 重启后第二次死锁 2 等待加锁writelog,已加锁recv 2等待加锁recv 3 等待加锁Recv 3 等待加锁recv
4 等待加锁Recv
4 等待加锁Writelog,已加锁recv
5已到sn打印,等待加锁writelog 5 等待加锁recv
6 等待加锁Recv
6 等待加锁recv
第一轮如果就出现死锁,则可检查锁配对和可能的程序出口上是否进行了开锁。
如果多轮运行后出现,且基本确认函数出口均解锁,则需要判断是否是内存越界,则需要用到工具:valgrind进行内存越界诊断。
发现出现不响应时首先查看是否出现核心转储,若没有则表明程序确实进入某种锁状态,按ctrl+c暂停程序