I'm trying to follow the procedure, explained under this Microsoft link, for finding a possible deadlock in my application.
In my case, I also start with the function !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
The second item mentions I need to go for thread 30d8
:
0:000> ~
...
59 Id: 3ff4.30d8 Suspend: 0 Teb: fe2a5000 Unfrozen
...
So, I might expect information about a critical section in thread 59, but while looking there:
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
Edit after first comment:
Unfortunately the command sosex.dlk
did not reveal any information, even after having run the !bhi
command.
As far as investigating 36b8
, also there there's not much information:
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
I'm not aware of the !findstack
feature, can you tell me what I'm doing wrong here?
0:000> !findstack CriticalSection
0:000> !findstack *!CriticalSection
0:000> !findstack RtlEnterCriticalSection
0:000> !findstack *CriticalSection*
=> always no results.
Thread 59 is owning the critical section already. That means it has called EnterCriticalSection
some time ago. You'll not see that in the debugger any more. That thread should call LeaveCriticalSection
somewhen. But at the moment it's waiting for something else to happen (WaitForSingleObject
on object 36b8
).
Next steps:
36b8
is, using !handle 36b8 f
.EnterCriticalSection
using !findstack
.If you suspect the deadlock to be caused by critical sections only, you can use !sosex.dlk
. Although SOSEX was designed for .NET deadlocks, it can also detect deadlocks in critical sections.