Home BlogThe Silent Standoff — Deadlocks and Power State Failures (0x9F & 0x15F)

The Silent Standoff — Deadlocks and Power State Failures (0x9F & 0x15F)

by dnaadmin

In our final installment of this introductory series, we move from runaway loops to the opposite problem: The Deadlock. This is where the system isn’t “busy”—it’s “stuck.”

Two or more threads are waiting for resources held by each other, and neither can proceed. In the Windows kernel, this frequently manifests during power transitions (like sleeping or hibernating), leading to the infamous 0x9F: DRIVER_POWER_STATE_FAILURE.


1. The Locking Hierarchy

Kernel drivers use various synchronization primitives to protect shared data:

  • Spinlocks: Fast, used at DISPATCH_LEVEL.
  • Mutexes/ERESOURCEs: Used at PASSIVE_LEVEL, allowing threads to wait (sleep) if the resource is busy.

The Deadlock Trap: Thread A acquires Lock 1 and tries to get Lock 2. Simultaneously, Thread B acquires Lock 2 and tries to get Lock 1. Both threads sit forever, and if one of those threads is required for a system-wide operation (like a shutdown), the Watchdog eventually triggers a BSOD.


2. Real Use Case: The Sleep-Timer Deadlock

Scenario: A laptop fails to enter “Sleep” mode. The screen goes black, the fans stay on for 30 seconds, and then it crashes with 0x9F.

Step 1: Analyze the Power IRP

For 0x9F, Parameter 1 tells us the type of violation. Usually, it’s 0x3 (A device object has been blocking an IRP for too long).

Run: !analyze -v

Then, find the pending IRP:

!irp <address_from_analyze>

Step 2: Finding the Blocker

The !irp command will show which driver is currently “owning” the power request.

Plaintext

>[0, 0]   0  0 ffffe001`1a2b3c40 00000000 fffff801`4b331010-fffff801`4b442020
           \Driver\MyUsbFilter   nt!PopRequestCompletion

Here, MyUsbFilter received a “Set Power” IRP but never passed it down or completed it.

Step 3: Thread Analysis

Why is the driver stuck? We look at the thread handling that IRP:

!thread <address>

The stack trace might look like this:

Plaintext

nt!KeWaitForSingleObject
MyUsbFilter!StopTrafficAndLock+0x45
MyUsbFilter!PowerDispatch+0x12

The Discovery: The driver is waiting for a Mutex to “Stop Traffic.” However, the thread that holds that Mutex is currently blocked waiting for the Power IRP to finish. This is a classic Circular Dependency.


3. Debugging Tools for Deadlocks

If you suspect a lock issue, WinDbg has specialized tools:

  • !locks: Displays all kernel resources and which threads own them. Look for “Threads Waiting.”
  • !deadlock: If you have Driver Verifier’s Deadlock Detection enabled, this command will explicitly map out the circular chain for you.
  • !ready: Shows all threads in a “Ready” state to see if anyone is being starved of CPU time.

4. Designing for Stability (Blog Advice)

  • Lock Ordering: Always acquire locks in the exact same order across all functions in your driver. If you take Lock A then Lock B in one place, never take Lock B then Lock A elsewhere.
  • Don’t Block in Power Paths: Power dispatch routines should be fast. If you need to wait for hardware, use a timeout.
  • Use Passive-Level Interrupts: If your hardware allows, handle complexity at PASSIVE_LEVEL where you have more flexibility with synchronization.

Summary of Resource & Power Bug Checks

CodeNameDescription
0x9FDRIVER_POWER_STATE_FAILUREA driver is inconsistent or slow during a power state change.
0x15FCONNECTED_STANDBY_WATCHDOG_TIMEOUTA specialized 0x9F for modern standby devices.
0xCBDRIVER_LEFT_LOCKED_PAGES_IN_PROCESSA driver failed to release memory or locks before a process ended.
0xDEPOOL_CORRUPTION_IN_FILE_AREAOften a deadlock between the Memory Manager and a File System driver.

Conclusion of the Series

Debugging is a mix of science and intuition. By mastering IRQLs, Pool Headers, DPCs, and Locking, you move from guessing why a system crashed to knowing exactly which line of code failed.

Happy Debugging!

You may also like

Leave a Comment