Debugger commands (!poaction, !poreqlist) that make my life easier (part 2)

Today’s commands are related to power, they are:

!podev (covered in the last topic)

!poreqlist will list all outstanding PIRPs on the machine that are a result of any driver calling PoRequestPowerIrp(). Remember how in the last topic, !podev did not tell you what the active deivce power irp was, only that there was an active irp? Well, !poreqlist fills in the gap.

First, let’s review !podev for a device object (which is the PS2 keyboard) which is about to process a Dx PIRP. We see that the dvact flag is set.

1: kd> !podev 0x8211c310
Device object is for:
DriverObject 82121f10
Current Irp 00000000 RefCount 0 Type 00000000 AttachedDev 8211c190 DevFlags 00002004 DO_POWER_PAGABLE
Device queue is not busy.
Device Object Extension: 8211c6a8:
PowerFlags: 00000400 =>SystemState=0 DeviceState=0 dvact
Dope: 00000000:

Now let’s use !poreqlist to fill in the gap and find the power irp itself (granted, you can look at the callstack of the power dispatch routine in this example, but assume you are not in that context).

1: kd> !poreqlist
All active Power Irps from PoRequestPowerIrp
FieldOffset = 00000004
Irp 825cef20 DevObj 822b11a0 \Driver\ACPI Ctx 00000005 * Wait Wake S4
Irp 82f50e28 DevObj 82292500 \Driver\ACPI Ctx 00000004 Wait Wake S3
Irp 836bce28 DevObj 8211c310 \Driver\i8042prt Ctx 00000003 Set Power D3 ShutdownType 2

Looking at the bold line above, we see the our devobj (8211c310) in the list and see its Dx power irp (836bce28). This is a pretty powerful command. For instance, this can let you debug an instance where you might be waiting for a device stack to power back up and you want to see the state of that stack’s device power irp.

Now let’s take a look at !poaction. !poaction can tell what the current power action (suspend, hibernate, turning off) is. What is more interesting about !poaction is that it shows you the order in which devices are powered off. This means that you can break into the debugger while your device is powering off and see the state of all the other devices on the machine. I won’t go into detail about all of the output given, but you should experiment with this on your own if you ever need to debug a dependency where your device requires another device to be powered up and that device is not a direct ancestor of your device in the tree

1: kd> !poaction
PopAction: 8055b418
State……….: 3 – Set System State
Updates……..: 0
Action………: Sleep
Lightest State.: Sleeping1
Flags……….: 3 QueryApps|UIAllowed
Irp minor……: SetPower
System State…: Sleeping3
Hiber Context..: 00000000

PopAction.DevState 819819e0
Irp minor……: SetPower
System State…: Sleeping3
Worker thread..: 820544e8
Status………: 0
Waking………: FALSE
Cancelled……: FALSE
Ignore errors..: FALSE
Ignore not imp.: FALSE
Wait any…….: FALSE
Wait all…….: FALSE
Present Irp Q..: Head:81981c5c Empty

Level 7 (81981c04) 0/17 Paged, Root-Enum
Level 5 (81981b74) 6/15 Paged, PnP
81b042a8: 822914c8 \Driver\Mouclass \Device\PointerClass0
81b8b450: 822913a8 \Driver\serenum
81f38a10: 8226b9b8 \Driver\redbook
81a66590: 8228c9b8 \Driver\redbook
81a15e70: 82291708 \Driver\Fdc
Level 4 (81981b2c) 0/2 Paged, PnP, Video
Level 3 (81981ae4) 0/40 Non-Paged, Root-Enum
Level 1 (81981a54) 0/34 Non-Paged, PnP
81aaf7f0: 822b6dc8 \Driver\usbuhci \Device\USBFDO-0
81adb840: 822b6ca8 \Driver\usbuhci \Device\USBFDO-1
82209fd8: 822b6b88 \Driver\usbuhci \Device\USBFDO-2
81f28ec8: 822b6a68 \Driver\usbuhci \Device\USBFDO-3
81a3bc68: 822b6948 \Driver\usbehci \Device\USBFDO-4

Pending irps:
Irp: 83968e70 Notify 00000000

Completed irps:
Irp: 82b22f48 Notify 00000000
Irp: 836b2f48 Notify 00000000
Irp: 82d08f00 Notify 00000000
Irp: 82b76f00 Notify 00000000
Irp: 833bef00 Notify 00000000
Irp: 834e4f00 Notify 00000000
Irp: 8363ef20 Notify 00000000
Irp: 824bce90 Notify 00000000
Irp: 836d6f48 Notify 00000000

Comments (3)

  1. SamuelChen says:

    As mention, "!poaction" can list all device that are powered

    off. But how can I know which device is not powered off?

    And can I trace all Power IRP through all driver?

  2. doronh says:

    The devices listed in the ReadySleep lists have not yet been powered off.  For instance, these devices have not yet been sent an Sx power PIRP.

        81aaf7f0: 822b6dc8 Driverusbuhci DeviceUSBFDO-0 
        81adb840: 822b6ca8 Driverusbuhci DeviceUSBFDO-1 
        82209fd8: 822b6b88 Driverusbuhci DeviceUSBFDO-2 
        81f28ec8: 822b6a68 Driverusbuhci DeviceUSBFDO-3 
        81a3bc68: 822b6948 Driverusbehci DeviceUSBFDO-4 

    As for tracing all power irps as they are created at runtime, you can do something like this

    nt!PoRequestPowerIrp “!devstack poi(@esp+4);g”

    which will break on each call to PoRequestPowerIrp (for both device and wait wake irps) and run !devstack on the first parameter passed to the function (which will be the PDO for the device stack) and then continue.  On my XP SP2 machine, this made power down painfully slow because of the expression after the function to break on so you might be better of with just a “bp nt!PoRequestPowerIrp”

  3. I posted about !poaction and !poreqlist about a year ago. I tend to use these extensions whenever I am