定位思路

1、使用top命令查看相关进程仍在运行,确认是进程卡死。
2、重新编译可调试版本,运行新版本,复现问题,GDB调试新版本。
3、分析堆栈信息及业务逻辑,找出卡死原因。
4、修改代码,重新编译进行验证。
1)若问题解决,则确认修改,合入原代码。
2)若问题未解决,增加定位信息,重新编译运行。
案例
问题现象:
某软件在服务器上运行出现卡死问题。
定位过程:
1、使用top命令查看进程仍存在,确认是卡死问题。
2、重新编译该程序为可调试版本,重新运行,复现问题,查询该进程PID号。
3、进入到程序的调测模式。
说明:2573为该程序PID号。

4、开启日志,将堆栈信息导出到文件。
5、查看线程状态。

绝大部分线程都处在等待状态__lll_lock_wait。其中,等待的锁变量主要有两个,resource1和resource2。
6、通过print命令查看,两个锁变量的信息。其中__owner表示当前该锁的持有者线程ID。

可见,resource1由线程3889持有未释放,resource2由线程3892持有未释放。
7、从上述收集的日志文件中找到ID为3889和3892的线程日志。

从这两个线程的状态信息可以看出,3889号线程持有了锁resource1,但是本身在请求resource2;而3892号线程持有了锁resource2,但是本身在请求resource1。这两个线程的锁调用关系构成了死锁条件导致无法退出,同时,其他所有依赖这两个锁的线程都陷入了等待状态。
8、根据上述堆栈信息,是threadOne和threadTwo直接相互调用导致死锁,查看业务代码逻辑,修改代码,重新编译,运行,问题未复现,确认修改代码合入,验证问题解决。
定位思路
1、使用top命令查看相关进程仍在运行,确认是进程卡死。
2、重新编译可调试版本,运行新版本,复现问题,GDB调试新版本。
3、分析堆栈信息及业务逻辑,找出卡死原因。
4、修改代码,重新编译进行验证。
1)若问题解决,则确认修改,合入原代码。
2)若问题未解决,增加定位信息,重新编译运行。
案例
问题现象:
某软件在服务器上运行出现卡死问题。
定位过程:
1、使用top命令查看进程仍存在,确认是卡死问题。
2、重新编译该程序为可调试版本,重新运行,复现问题,查询该进程PID号。
3、进入到程序的调测模式。
说明:2573为该程序PID号。
4、开启日志,将堆栈信息导出到文件。
5、查看线程状态。
绝大部分线程都处在等待状态__lll_lock_wait。其中,等待的锁变量主要有两个,resource1和resource2。
6、通过print命令查看,两个锁变量的信息。其中__owner表示当前该锁的持有者线程ID。
可见,resource1由线程3889持有未释放,resource2由线程3892持有未释放。
7、从上述收集的日志文件中找到ID为3889和3892的线程日志。
从这两个线程的状态信息可以看出,3889号线程持有了锁resource1,但是本身在请求resource2;而3892号线程持有了锁resource2,但是本身在请求resource1。这两个线程的锁调用关系构成了死锁条件导致无法退出,同时,其他所有依赖这两个锁的线程都陷入了等待状态。
8、根据上述堆栈信息,是threadOne和threadTwo直接相互调用导致死锁,查看业务代码逻辑,修改代码,重新编译,运行,问题未复现,确认修改代码合入,验证问题解决。