续:
1.这是什么类型的电源管理IRP,即他的MINOR FUNCTION是什么?
2.哪个物理设备对象是该IRP的接收者?
3.这种MAJOR/MINOR组合的IRP系统能够接收的处理时间范围是多少?
4.而这个IRP到底又被阻塞了多少时间?
5.为什么这个IRP会被阻塞?
以上五个问题,我已经在上篇 --第五篇:风起于青萍之末-电源管理请求案例分析(上) 解决了面前两个.
http://blog.csdn.net/u013140088/article/details/18180249
这个IRP是系统发给GOLDEN TREE上第四级的SS HUB的SET D3的电源管理IRP.
我们接下来继续分析剩下的几个问题.
首先,我们看一下,!analyze -v给出的栈回溯(如下):
"望文生义", 系统在IDLE进程中,当系统处于DISPATCH_LEVEL时,调用了DPC处理例程,通过"看门狗"发现了"超时IRP", 于是又通过BugCheck触发了BSOD.
****************************************************************************
STACK_TEXT:
836c59d8 82522894 0000009f 00000003 85be34c0 nt!KeBugCheckEx
836c5a10 825228c7 a8124490 00000000 825fb558 nt!PopIrpWatchdogBugcheck+0xb0
836c5a28 825c56fb a81244d8 a8124490 4cbf50c5 nt!PopIrpWatchdog+0x28
836c5ae0 825c6e81 836ae330 836c5b28 b74a2900 nt!KiExecuteAllDpcs+0x1f2
836c5c00 8255a3f4 00000000 0000000e 00000000 nt!KiRetireDpcList+0xed
836c5c04 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x38
****************************************************************************
可以得出的结论是,触发BSOD的context/thread并非是发出这个"TIME OUT POWER IRP"的context/thread.
所以,我们得跳到发出该IRP的thread寻找一些"蛛丝马迹".
幸运的是!poaction这个不被微软公开的WINDBG命令,已经给出了我们想要的线程指针.
**************************************************************************************************************************************************************
IRP: ab7b4aa0 (set/S4), PDO: 85be34c0, CURRENT: baf54bf8, NOTIFY: 86a3e038
IRP: bcd5eaa0 (set/D3,), PDO: 85be34c0, CURRENT: baf54bf8
THREAD: 8bc34200 (dynamic), IRP: bcd5eaa0, DEVICE: 86a235e8
**************************************************************************************************************************************************************
在前路迷茫的时期,我打算看一看这个IRP, 发出该IRP的THREAD的详细内容,以及相关的栈回溯.
**************************************************************************************************************************************************************
Irp is active with 35 stacks 33 is current (= 0xbcd5ef90)
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 10 00000000 00000000 00000000-00000000
Args: 00000000 00000000 00000000 00000000
>[ 16, 2] 0 e1 baf54bf8 00000000 828b567f-bcd5efb4 Success Error Cancel pending
\Driver\USBHUB3 nt!IovpInternalCompletionTrap
Args: 00015400 00000001 00000004 00000003
[ 16, 2] 0 e1 86a235e8 00000000 8249ae8b-8ba5c008 Success Error Cancel pending
\DRIVER\VERIFIER_FILTER nt!PopRequestCompletion
Args: 00015400 00000001 00000004 00000003
[ 0, 0] 0 0 00000000 00000000 00000000-8ba5c008
Args: 00000000 00000000 00000000 00000000
THREAD 8bc34200 Cid 0004.0b8c Teb: 00000000 Win32Thread: 00000000 WAIT: (Executive) KernelMode Non-Alertable
bfd52afc NotificationEvent
Not impersonating
DeviceMap 83407bf8
Owning Process 85b64a00 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 157498 Ticks: 3840 (0:00:01:00.000)
Context Switch Count 196 IdealProcessor: 0
UserTime 00:00:00.000
KernelTime 00:00:00.031
Win32 Start Address nt!PopIrpWorker (0x8249598b)
Stack Init c57adca0 Current c57ad7f4 Base c57ae000 Limit c57ab000 Call 0
Priority 13 BasePriority 13 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr Args to Child
c57ad80c 8243b319 00003100 8bc34258 8bc34200 nt!KiSwapContext+0x19 (FPO: [Uses EBP] [1,0,4])
c57ad884 8243aa74 8bc34200 8bc342e0 00000002 nt!KiCommitThreadWait+0x280 (FPO: [5,23,4])
c57ad920 828bb759 bfd52afc 00000000 00000000 nt!KeWaitForSingleObject+0x26c (FPO: [Non-Fpo])
c57ad954 914b2732 bfd52afc 00000000 00000000 nt!VerifierKeWaitForSingleObject+0x120 (FPO: [Non-Fpo])
c57ad984 9149f201 bfd52afc 914ba9fc 402ad918 UsbHub3!HUBMISC_WaitForSignal+0x59 (FPO: [Non-Fpo])
c57ad9b0 8683db58 402ad918 00000004 86891d88 UsbHub3!HUBFDO_EvtDeviceD0Exit+0xf4 (FPO: [2,3,4])
c57ad9d4 8683e2d3 c57ada78 8683ce18 81c18ce8 Wdf01000!FxPkgPnp::PowerGotoDxIoStopped+0xb3 (FPO: [0,1,4])
c57ad9dc 8683ce18 81c18ce8 00001000 86891d60 Wdf01000!FxPkgPnp::PowerGotoDNotZeroIoStopped+0xd (FPO: [Non-Fpo])
c57ada78 8683c2e5 81c18ce8 0000031c 81c18e08 Wdf01000!FxPkgPnp::PowerEnterNewState+0x15c (FPO: [Non-Fpo])
c57adaa0 8683c0e1 81c18ce8 c57adacc c57adb10 Wdf01000!FxPkgPnp::PowerProcessEventInner+0x167 (FPO: [2,3,4])
c57adad8 8683616b 81c18ce8 868360d6 919faee8 Wdf01000!FxPkgPnp::PowerProcessEvent+0x185 (FPO: [1,7,4])
c57adae0 868360d6 919faee8 81c18ce8 c57adb18 Wdf01000!FxPkgFdo::DispatchDeviceSetPower+0x89 (FPO: [0,0,0])
c57adaf0 86832d85 81c18ce8 c57adb10 bfd527a4 Wdf01000!FxPkgFdo::_DispatchSetPower+0x28 (FPO: [Non-Fpo])
c57adb18 8682d52e bcd5eaa0 baf54bf8 bcd5eaa0 Wdf01000!FxPkgPnp::Dispatch+0x1ad (FPO: [1,3,4])
c57adb40 8682d39f 02f54bf8 bcd5eaa0 baf54bf8 Wdf01000!FxDevice::Dispatch+0x155 (FPO: [Non-Fpo])
c57adb5c 82495ee0 baf54bf8 bcd5eaa0 bcd5eaa0 Wdf01000!FxDevice::DispatchWithLock+0x77 (FPO: [Non-Fpo])
c57adb74 828abf8d bcd5eaa0 828abcb7 baf54bf8 nt!IopPoHandleIrp+0x2a (FPO: [Non-Fpo])
c57adb8c 8243a066 824d6147 bcd5efac bcd5efd0 nt!IovCallDriver+0x2d5 (FPO: [Non-Fpo])
c57adba0 824d6147 c57adbc8 828c396e baf54bf8 nt!IofCallDriver+0x73 (FPO: [Non-Fpo])
c57adba8 828c396e baf54bf8 bcd5eaa0 bcd5eaa0 nt!IoCallDriver+0x10 (FPO: [Non-Fpo])
c57adbc8 82495bf0 86a236a0 bcd5eaa0 8bc34200 nt!ViFilterDispatchPower+0x53 (FPO: [Non-Fpo])
c57adc34 82470b1b 8e06dbd0 c78e8a16 00000000 nt!PopIrpWorker+0x265 (FPO: [1,19,4])
c57adc70 8255a579 8249598b 8e06dbd0 00000000 nt!PspSystemThreadStartup+0x4a (FPO: [Non-Fpo])
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x19
**************************************************************************************************************************************************************
内容有点长,我对一些内容稍加注释:
1. 该IRP所对应的设备栈达到35个之多,目前停留(pending)在第33个处
我想,是因为该栈对应的Completion routine得不到调用,导致了该PENDING.
那为什么该Completion routine得不到调用呢?
为什么是停在第33处,而不是第34处呢?
第34处为什么也是PENDING状态?
这些问题,一起抛过来的时候,我确实也招架不住.
如果有哪位大牛,能解释一下,热烈欢迎.
2.该BSOD是发生在DV(Driver verifer) I/O verification 被启用的状态下的.
所以,USB3HUB驱动下面会有一个DRIVER VERIFIER的底层过滤驱动.
3. 发出该IRP的THREAD隶属于SYSTEM这个"捏造"进程,
这个线程在kernel环境中,只运行了31ms.
既然隶属于SYSTEM进程,就无从说user环境中的时间了,必定是0.
这个线程发出了该IRP之后就进入了睡眠状态,被换出调度队列了.
4.bfd52afc NotificationEvent
线程既然进入睡眠状态,必定有一个唤醒他的事件,就是这个bfd52afc NotificationEvent.
看到这里,我的判断是,该EVENT是由另外的线程来设置的.
那是哪个线程呢?
为什么另外那个线程没有设置该EVENT呢?
是不是如果设置了该EVENT, 发出这个IRP的线程就能完成他(IRP), 从而解决了IRP的超时问题呢?
这些问题,我也不能解决. 请见5.
5.
***********************************************************************
kd> dt nt!_kevent bfd52afc -r
+0x000 Header : _DISPATCHER_HEADER
+0x000 Type : 0 ''
+0x001 TimerControlFlags : 0 ''
+0x001 Absolute : 0y0
+0x001 Wake : 0y0
+0x001 EncodedTolerableDelay : 0y000000 (0)
+0x001 Abandoned : 0 ''
+0x001 Signalling : 0 ''
+0x002 ThreadControlFlags : 0x4 ''
+0x002 CycleProfiling : 0y0
+0x002 CounterProfiling : 0y0
+0x002 GroupScheduling : 0y1
+0x002 AffinitySet : 0y0
+0x002 Reserved : 0y0000
+0x002 Hand : 0x4 ''
+0x002 Size : 0x4 ''
+0x003 TimerMiscFlags : 0 ''
+0x003 Index : 0y0
+0x003 Processor : 0y00000 (0)
+0x003 Inserted : 0y0
+0x003 Expired : 0y0
+0x003 DebugActive : 0 ''
+0x003 DpcActive : 0 ''
+0x000 Lock : 0n262144
+0x000 LockNV : 0n262144
+0x004 SignalState : 0n0
+0x008 WaitListHead : _LIST_ENTRY [ 0x8bc342e0 - 0x8bc342e0 ]
+0x000 Flink : 0x8bc342e0 _LIST_ENTRY [ 0xbfd52b04 - 0xbfd52b04 ]
+0x004 Blink : 0x8bc342e0 _LIST_ENTRY [ 0xbfd52b04 - 0xbfd52b04 ]
***********************************************************************
我以为,通过这个EVENT就能得到与它相关的THREAD,其中一个是等待中的,另外一个是设置他的.
***********************************************************************
4: kd> dt nt!_kwait_block 0x8bc342e0
+0x000 WaitListEntry : _LIST_ENTRY [ 0xbfd52b04 - 0xbfd52b04 ]
+0x008 WaitType : 0x1 ''
+0x009 BlockState : 0x2 ''
+0x00a WaitKey : 0
+0x00c Thread : 0x8bc34200 _KTHREAD
+0x00c NotificationQueue : 0x8bc34200 _KQUEUE
+0x010 Object : 0xbfd52afc Void
+0x014 SparePtr : (null)
这个应该是发出IRP,等EVENT被设置的THREAD
***********************************************************************
4: kd> dt nt!_kwait_block 0xbfd52b04
+0x000 WaitListEntry : _LIST_ENTRY [ 0x8bc342e0 - 0x8bc342e0 ]
+0x008 WaitType : 0 ''
+0x009 BlockState : 0 ''
+0x00a WaitKey : 0
+0x00c Thread : 0x4a6450d0 _KTHREAD
+0x00c NotificationQueue : 0x4a6450d0 _KQUEUE
+0x010 Object : 0x09042a0c Void
+0x014 SparePtr : 0x04006400 Void
那这个是不是应该是设置这个EVENT的THREAD呢?
***********************************************************************
可惜的是:
***********************************************************************
4: kd> !thread 0x4a6450d0
4a6450d0: Unable to get thread contents
4: kd> dt nt!_kevent 0x09042a0c
+0x000 Header : _DISPATCHER_HEADER
Memory read error 09042a0c
***********************************************************************
看到这样的输出,感觉到,从这要路走到黑是没有办法了.
之后,没有办法的办法的时候,
我又尝试了一下:
1. !locks命令,看有没有死锁的问题产生.
2. 查看
IRP: ab7b4aa0 (set/S4), PDO: 85be34c0, CURRENT: baf54bf8, NOTIFY: 86a3e038
这个IRP的执行过程与结果, 弄清楚NOTIFY是什么数据结构,他的作用是什么? 是对应的EVENT, 还是表明这个IRP已经成功完成了?
***********************************************************
4: kd> !pool 86a3e038
Pool page 86a3e038 region is Nonpaged pool
*86a3e000 size: 1d8 previous size: 0 (Allocated) *Dnod
DevNode 0x86a3e008 for PDO 0x85be34c0
InstancePath is "USB\VID_2109&PID_8110\9&1a101867&0&1"
ServiceName is "USBHUB3"
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)
kd> dtnt!_device_node
+0x030 Notify : _PO_DEVICE_NOTIFY
原来, 这个NOTIFY: 86a3e038就是
device node数据结构0x30处的一个子数据结构. 而这个DEV NODE就是对应于SS HUB4.
kd> dt _PO_DEVICE_NOTIFY 0x86a3e008+30
nt!_PO_DEVICE_NOTIFY
+0x000 Link : _LIST_ENTRY [ 0xbaeafcf4 - 0xbaeafcf4 ]
+0x008 PowerChildren : _LIST_ENTRY [ 0x86a3e040 - 0x86a3e040 ]
+0x010 PowerParents : _LIST_ENTRY [ 0x86a3e048 - 0x86a3e048 ]
+0x018 TargetDevice : 0x86a235e8 _DEVICE_OBJECT
+0x01c OrderLevel : 0x3 ''
+0x020 DeviceObject : 0x85be34c0 _DEVICE_OBJECT
+0x024 DeviceName : (null)
+0x028 DriverName : 0xb6c67ee0 -> 0x5c
+0x02c ChildCount : 2
+0x030 ActiveChild : 0
+0x034 ParentCount : 1
+0x038 ActiveParent : 1
***********************************************************
可惜的是, 微软并没有公开这个_PO_DEVICE_NOTIFY数据结构的说明.
因些,我感觉,从DUMP FILE中突破存在了较大的困难, 是不是应该换一条路子呢?