一.问题现象

客户端收不到服务端的请求,查看服务端不再响应。现将定位过程记录如下。

二.问题调试过程

使用gdb attach上该服务的进程后,发现有工作线程卡在了锁的获取上,如图

clipboard.png
该进程的15号线程,停在了获取锁上,切到该线程的第3帧,查看该信号量的信息,如图

clipboard.png

使用命令
ipcs -s -i 35848295
查看占有该信号量的线程,输出如图所示:

clipboard.png
可以看到占有该信号量的进程是9013进程。

接着使用gdb attach上9013号进程。
其中一个线程的调用栈如图所示

clipboard.png
看上去,该线程也在获取锁,同时仔细观察了其他线程锁,也没找到有等待锁的地方。难道是锁重入了,继续看上面的栈帧,并对照代码排查,发现12号帧已经获取了该锁。至此问题查明。

三.修改和防范措施

windows下进程锁同一个线程内是可以重入的,linux下不可重入(可以写个简单的单线程程序验证)。在linux下,应该避免同一线程进程锁的重入。
修改方法:减少锁第一次获取时的使用范围,及时释放。


one_piece
26 声望8 粉丝