使用!dlk命令调试死锁将返回未知的线程名

时间:2018-10-10 13:00:26

标签: c# multithreading debugging deadlock windbg

我正在尝试使用SOSEX命令!dlk调试进程中的死锁 我得到以下输出:

*DEADLOCK DETECTED*

CLR thread 0xac holds the lock on SyncBlock 00000012ac132068 OBJ:00000012830d66a0[System.Object]
and is waiting for the lock on SyncBlock 00000012ae4ba6b8 OBJ:00000012808391f8[System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib],[CaptureServices.GenericInfrastructure.Controlling.CapManager.MO.CallRecorder.ICallRecorder, Capture Manager]]]

CLR thread 0x9a holds the lock on SyncBlock 00000012ae4ba6b8 OBJ:00000012808391f8[System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib],[CaptureServices.GenericInfrastructure.Controlling.CapManager.MO.CallRecorder.ICallRecorder, Capture Manager]]]
and is waiting for the lock on SyncBlock 00000012ac132068 OBJ:00000012830d66a0[System.Object]

我希望能够获得这些线程的调用堆栈,但是我无法在线程列表中找到线程ID(0xac,0x9a)。 我尝试了以下命令,但以上结果均未列出上述线程:

  1. -应该显示所有线程(托管和非托管)
  2. 〜* e!clrstack -应该显示所有线程的调用堆栈
  3. 〜* e!dumpstack -转储所有托管线程

还有另一种方法可以查看死锁中可能丢失的线程的调用堆栈吗?我什至尝试将线程ID转换为十进制,但找不到匹配的线程ID。

谢谢

1 个答案:

答案 0 :(得分:1)

following article 帮助我如何阅读!dlk命令的结果。 根据该文章,例如,如果我们在线程0xac中发现了死锁:

CLR **thread 0xac** holds the lock on SyncBlock 00000012ac132068 OBJ:00000012830d66a0[System.Object]

!thread命令的结果具有3个“ ID”列:

  1. 逻辑线程ID(第一列)
  2. CLR ID(第二列)
  3. OSID(第3列)

!dlk中的线程ID实际上是!thread结果中的CLR ID: (ac)=172。CLRID 172是线程177。

0:000> !threads
                                                                                                        Lock  
       ID OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
 177  172 1188 00000012abfcaee0  3029220 Preemptive  0000000000000000:0000000000000000 00000012f0e94d70 3     MTA (Threadpool Worker) 

现在我可以通过以下命令切换到线程177:〜177s

并通过以下命令查看线程的调用堆栈:!clrstack