I'm trying to better understand the !locks command in WinDbg. Say, I have a crash dump with a bunch of waiting (deadlocked) threads. If I run !locks the WinDbg gives me a long list of threads that obtained a shared access to the ERESOURCE and then lower a long list of threads that are waiting on exclusive access to it.
So if I do !thread <ethread_addr> on any of the threads from those two lists, the command rightfully so tells me that thread's state is: "WAIT (Executive)" for the first list and "WAIT (WrResource)" for the second list.
But then on the next line I see what the thread is waiting on:
<kernel_address> SynchronizationEvent
So two part question:
Why is it SynchronizationEvent when the threads were waiting on the ERESOURCE? After all I got them from the !locks command.
Why is the <kernel_address> for the SynchronizationEvent different for each thread that is in the list that was returned by the !locks command? I thought they were all waiting on the same ERESOURCE, that got them stuck in the first place.
It doesn't literally mean a KEVENT. This is a generic use of the word. All (most) of the kernel synchronization objects have the same basic construct at the bottom, with fluff added on top., so the scheduler doesn't have to deal with 15 different kinds of objects.
When a thread waits for exclusive access of an executive resource (ERESOURCE) that is currently owned, it waits on a synchronization event object (ExclusiveWaiters member in the ERESOURCE structure). When a synchronization event is set, it enters the signaled state, which releases the only thread waiting for the event, and then the event immediately enters the non-signaled state. If no threads are waiting for the event, the event state remains signaled. This property allows threads to synchronize when an event is signaled. This property is also used for exclusive resource waiting -- only one of the waiter threads will wake up when the event is signaled.
Internally, ExclusiveWaiters is a pointer to KEVENT and SharedWaiters is a pointer to KSEMAPHORE.
NumberOfSharedWaiters/NumberOfExclusiveWaiters are essentially what they are named and are used to check the waiting state of a resource (either shared or exclusive).
The so called "fast" executive resources are used internally by the file system stack and provide somewhat more optimized performance in some scenarios.