I’ve previously explained how to debug a Stop 0x9F with a blocked IRP, although, there is a different situation when the !irp, !devobj and !devstack extensions are not viable option for debugging. This is because the cause of the crash is slightly different.
From the parameters provided by the bugcheck, we get a general idea of the problem, and what happened, basically a thread was holding a lock, which wasn’t released, causing the synchronization to time out.
From my understanding, the lock was never released by the thread, since it’s wait wasn’t satisfied, it wasn’t able to obtain the objects it was waiting for.
We can view which objects the locked thread was waiting for, with the !thread extension and parameter 3.
We can see that the thread is waiting for three Event objects, which are all Notification Events,
the thread is waiting for the completion of a certain event of procedure, once this has become complete, the Event objects will switch from Non-Signaled to Signaled, and will release the thread(s) from it’s waiting state. Once a thread has left it’s wait state, then it can resume it’s normal operations.
From the call stack, there is further evidence to support that thread holding the lock is waiting for multiple Event objects: nt!KiCommitThreadWait and nt!KeWaitForMultipleObjects.
Events can be exposed to Device drivers, so let’s check which drivers may be causing the thread to wait. I dumped the raw stack of the current thread we were viewing, and found a very outdated ATI graphics card driver.
Two useful data structures you could use in a situation like this are: nt!_DISPATCHER_HEADER and nt!_KOBJECTS. The type field of the Dispatcher data structure will correspond to the a value within the Objects data structure, which in turn will indicate the type of object the thread is waiting for.