首页 > 代码库 > 调试死锁问题

调试死锁问题

今天遇到了一个应用程序死锁了,由于是在测试人员的环境中,所以生成了一个dump文件,生成dump文件的方法可以用任务管理器,在任务管理器的进程列表中点击右键,选择“Create Dump File”,就会为该进程生成一个mini dump文件。

由于是自己的程序,所以一般进程对应的pdb文件和源代码文件都有。下面以visual studio 2010和windbg分别说明如何定位到死锁代码。

(1)windbg方法。

因为我们猜测该程序死锁了,所以用windbg打开dump文件,同时设置符号路径,执行步骤

第一步:执行命令!locks

结果如下:

0:000> !locks

CritSec +13a8e18 at 00000000013a8e18
WaiterWoken        No
LockCount          9
RecursionCount     1
OwningThread       f34
EntryCount         0
ContentionCount    9
*** Locked

Scanned 31 critical sections

请注意 Owning Thread f34和***Locked.表明线程f34在等待所。

第二步:执行~命令,结果如下:

0:000> ~
.  0  Id: 1614.16b8 Suspend: 0 Teb: 00007ff7`b4cbd000 Unfrozen
   1  Id: 1614.ff0 Suspend: 0 Teb: 00007ff7`b4cb9000 Unfrozen
   2  Id: 1614.a94 Suspend: 0 Teb: 00007ff7`b4cb7000 Unfrozen
   3  Id: 1614.f34 Suspend: 0 Teb: 00007ff7`b4b8e000 Unfrozen
   4  Id: 1614.1370 Suspend: 0 Teb: 00007ff7`b4b8c000 Unfrozen
   5  Id: 1614.4ac Suspend: 0 Teb: 00007ff7`b4b8a000 Unfrozen
   6  Id: 1614.1054 Suspend: 0 Teb: 00007ff7`b4b88000 Unfrozen
   7  Id: 1614.76c Suspend: 0 Teb: 00007ff7`b4b86000 Unfrozen
   8  Id: 1614.b70 Suspend: 0 Teb: 00007ff7`b4b84000 Unfrozen
   9  Id: 1614.1ad0 Suspend: 0 Teb: 00007ff7`b4b80000 Unfrozen
  10  Id: 1614.184c Suspend: 0 Teb: 00007ff7`b4cb5000 Unfrozen
  11  Id: 1614.114c Suspend: 0 Teb: 00007ff7`b4cb3000 Unfrozen
  12  Id: 1614.161c Suspend: 0 Teb: 00007ff7`b4b7e000 Unfrozen
  13  Id: 1614.17b8 Suspend: 0 Teb: 00007ff7`b4cbb000 Unfrozen
  14  Id: 1614.15c Suspend: 0 Teb: 00007ff7`b4b82000 Unfrozen
  15  Id: 1614.1900 Suspend: 0 Teb: 00007ff7`b4b7c000 Unfrozen
  16  Id: 1614.c6c Suspend: 0 Teb: 00007ff7`b4b7a000 Unfrozen
  17  Id: 1614.17cc Suspend: 0 Teb: 00007ff7`b4b78000 Unfrozen

找到f34线程的编码为3

第三步:执行命令 ~3 kb查看3号线程堆栈,结果如下:

0:000> ~3 kb
RetAddr           : Args to Child                                                           : Call Site
00007ffa`ab1c1148 : 00000000`01551080 00000000`00010100 ffffffff`fffffffe 00000000`00000000 : ntdll!ZwWaitForSingleObject+0xa
00007ffa`a63c6ea0 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000344 : KERNELBASE!WaitForSingleObjectEx+0x94

果然在等待锁。

这就找到了死锁位置,但是往往并不是仅仅因为这里代码的问题,而是还有另外一个地方在使用锁不正确导致的。

2)用visual studio 2010

第一步:和windbg方法一样,打开dump文件,配置符号路径,通常还需要load系统库的符号,因为默认没有系统库文件的调试符号。

第二步:vc中并没有像windbg那样的命令!locks来显示锁的情况,只能靠自己分析了。但是也提供了一个很不错的方法,点击“debug"菜单,选择”窗口“子菜单,再选择”parallel stacks“菜单,会显示所有的线程及其堆栈,如同windbg的~* kb命令一样,非常有用。如图所示:

第三步:慢慢分析,看看哪些线程在等待锁,和windbg一样,也可以很快发现死锁的位置。





调试死锁问题