如何找到僵局?

时间:2018-10-05 08:48:48

标签: locking deadlock windbg dump

我正在尝试按照this Microsoft link中所述的过程在我的应用程序中查找可能的死锁。

就我而言,我还从函数!locks开始:

CritSec +1130780 at 01130780
WaiterWoken        No
LockCount          0
RecursionCount     1
OwningThread       1624
EntryCount         0
ContentionCount    8
*** Locked

CritSec Wldap32!SelectLock1+0 at 7630a1b0
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       30d8
EntryCount         0
ContentionCount    219
*** Locked

CritSec Wldap32!SelectLock2+0 at 7630a168
WaiterWoken        No
LockCount          0
RecursionCount     1
OwningThread       1624
EntryCount         0
ContentionCount    47d
*** Locked

CritSec +cd6838 at 00cd6838
WaiterWoken        No
LockCount          1
RecursionCount     1
OwningThread       4584
EntryCount         0
ContentionCount    184
*** Locked

Scanned 107 critical sections

第二项提到我需要进入线程30d8

0:000> ~
...
  59  Id: 3ff4.30d8 Suspend: 0 Teb: fe2a5000 Unfrozen
...

因此,我可能希望在线程59中找到有关关键部分的信息,但是在查找该信息时:

  59  Id: 3ff4.30d8 Suspend: 0 Teb: fe2a5000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 0a48f4c4 74de9220 000036b8 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
01 0a48f574 74df376d 0d7acba0 00000000 00000000 IPHLPAPI!IcmpSendEcho2Ex+0x208
02 0a48f5ac 74df37a7 0d7acba0 00000000 00000000 IPHLPAPI!IcmpSendEcho2+0x2d
03 0a48f5e0 76303545 0d7acba0 bdd2500a 0a48f61f IPHLPAPI!IcmpSendEcho+0x27
04 0a48f6c0 762e0a46 0a48f79c 0c2180a0 0a08d660 Wldap32!LdapPingServer+0xa1
05 0a48f708 762c4ca0 00001363 0c3f2ba0 00000000 Wldap32!DrainWinsock+0x1c69a
06 0a48f778 762c6eae 00002774 00000000 0a48f79c Wldap32!LdapWaitForResponseFromServer+0x767
07 0a48f7d0 762c7bf9 00000000 0a48f850 0a48f9d4 Wldap32!ldap_result_with_error+0xf2
08 0a48f7f8 002c3a9b 0a08d88c 00001363 00000000 Wldap32!ldap_result+0x59
09 0a48faf8 002bcc1e 04059930 569939a1 00c21220 <Application>!CActiveDirectoryInfo::LDAPNotificationFunc+0xe5b
0a 0a48fb24 002c41a0 04059930 569939e5 7437f28e <Application>!CActiveDirectoryInfo::LDAPNotification_Protected+0xbe
0b 0a48fb60 7437f2e9 04059930 22a3f765 7437f28e <Application>!LDAPNotification+0x50
0c 0a48fb98 7437f2cd 7437f28e 0a48fbb8 75547c04 msvcr110!_beginthreadex+0xb4
0d 0a48fba4 75547c04 026f2b28 75547be0 238314af msvcr110!_endthreadex+0x102
0e 0a48fbb8 77d9ad2f 026f2b28 21045533 00000000 kernel32!BaseThreadInitThunk+0x24
0f 0a48fc00 77d9acfa ffffffff 77d800c7 00000000 ntdll!__RtlUserThreadStart+0x2f
10 0a48fc10 00000000 7437f28e 026f2b28 00000000 ntdll!_RtlUserThreadStart+0x1b

在第一个评论后编辑:

不幸的是,即使运行了sosex.dlk命令后,命令!bhi也没有显示任何信息。

就调查36b8而言,也没有太多信息:

0:000> !handle 36b8 f
Handle 000036b8
  Type          Event
  Attributes    0
  GrantedAccess 0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount   2
  PointerCount  65538
  Name          <none>
  Object specific information
    Event Type Auto Reset
    Event is Waiting

我不知道!findstack功能,您能告诉我我在做什么错吗?

0:000> !findstack CriticalSection
0:000> !findstack *!CriticalSection
0:000> !findstack RtlEnterCriticalSection
0:000> !findstack *CriticalSection*
=> always no results.

2 个答案:

答案 0 :(得分:1)

您应该查看关闭ldap连接对象上的ping。如果您要访问此调用栈,则通常意味着域控制器与调用应用程序服务器之间无法进行ICMP / ping操作(您可以使用应用程序服务器中的ping命令行工具对此进行测试;如果该工具挂起或命中超时,则导致与应用程序相同的挂起)。

如果您不拥有进行基础ldap调用的库,则应将网络设置为允许或拒绝ping,而不要丢弃它们。

答案 1 :(得分:0)

线程59已拥有关键部分。这意味着它在一段时间前已调用EnterCriticalSection。您将不会再在调试器中看到它。该线程应该在某个时候调用LeaveCriticalSection。但是目前,它正在等待其他事情发生(对象WaitForSingleObject上的36b8)。

下一步:

  • 使用36b8找出!handle 36b8 f是什么。
  • 该关键部分可能正在等待与59不同的线程。因此,请使用EnterCriticalSection注意!findstack

如果您认为死锁仅是由关键部分引起的,则可以使用!sosex.dlk。尽管SOSEX专为.NET死锁而设计,但它也可以检测关键部分中的死锁。