第六篇:风起于青萍之末-电源管理请求案例分析(中)

续:


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中突破存在了较大的困难, 是不是应该换一条路子呢?






你可能感兴趣的:(windows,host,dbg,usb3.0,BSOD,dump分析,xHCI)