我调试一个过程,就像是冷冻:调试NotificationEvent在内核调试(Windows)中
- 我怀疑的根本原因是低于
THREAD 877f4030 Cid 0568.0fb8
线程被阻塞在用户模式调用GetOverlappedResult
。
我已打开kd.exe
的转储。
也就是说,我很想知道更多关于NotificationEvent
这显然永远不会释放我们的线程。
在线程信息有:
879f6fdc NotificationEvent
在什么类型,我应该投地址879f6fdc
?或者我应该在哪个结构域中搜索它,以便理解或者了解阻碍情况的线索?
就Thread Thread而言,此线程当前不会列出任何处于非期望或未完成状态的IRP。
下面为相应的线程整个线程信息:
THREAD 877f4030 Cid 0568.0fb8 Teb: 7ff3d000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
879f6fdc NotificationEvent
Not impersonating
DeviceMap 89809fc8
Owning Process 87950030 Image: OurProduct.exe
Attached Process N/A Image: N/A
Wait Start TickCount 1472232 Ticks: 5394 (0:00:01:24.146)
Context Switch Count 2791788 IdealProcessor: 0
UserTime 00:00:06.848
KernelTime 00:00:09.890
Win32 Start Address MSVCR120!_threadstartex (0x721fbfb4)
Stack Init 8c761fd0 Current 8c761bc8 Base 8c762000 Limit 8c75f000 Call 0
Priority 8 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
Kernel stack not resident.
ChildEBP RetAddr Args to Child
8c761be0 824cfced 877f4030 00000000 8ab36120 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
8c761c18 824ceb4b 877f40f0 877f4030 879f6fdc nt!KiSwapThread+0x266
8c761c40 824c856f 877f4030 877f40f0 00000000 nt!KiCommitThreadWait+0x1df
8c761cb8 8267ae07 879f6fdc 00000006 826bca01 nt!KeWaitForSingleObject+0x393
8c761d20 8248f8a6 00001018 00000000 00000000 nt!NtWaitForSingleObject+0xc6
8c761d20 774f7094 00001018 00000000 00000000 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ 8c761d34)
09f9f61c 774f6a24 758b179c 00001018 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
09f9f620 758b179c 00001018 00000000 00000000 ntdll!NtWaitForSingleObject+0xc (FPO: [3,0,0])
09f9f68c 758b7841 00001018 ffffffff 00000000 KERNELBASE!WaitForSingleObjectEx+0x98 (FPO: [Non-Fpo])
09f9f6a0 758cb9e1 00001018 ffffffff 064f3d10 KERNELBASE!WaitForSingleObject+0x12 (FPO: [Non-Fpo])
09f9f6b8 745be159 00001018 0639ee0c 09f9f6ec KERNELBASE!GetOverlappedResult+0x57 (FPO: [Non-Fpo])
什么是继续并知道哪些事件或同步机制是不完善的正确方法?
在NotificationEvent地址一些命令:
0: kd> !object 879f6fdc
879f6fdc: Not a valid object (ObjectType invalid)
0: kd> dt nt!_KEVENT 879f6fdc
+0x000 Header : _DISPATCHER_HEADER
然后:
0: kd> dt nt!_DISPATCHER_HEADER 879f6fdc
+0x000 Type : 0 ''
+0x001 TimerControlFlags : 0 ''
+0x001 Absolute : 0y0
+0x001 Coalescable : 0y0
+0x001 KeepShifting : 0y0
+0x001 EncodedTolerableDelay : 0y00000 (0)
+0x001 Abandoned : 0 ''
+0x001 Signalling : 0 ''
+0x002 ThreadControlFlags : 0x4 ''
+0x002 CpuThrottled : 0y0
+0x002 CycleProfiling : 0y0
+0x002 CounterProfiling : 0y1
+0x002 Reserved : 0y00000 (0)
+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 ActiveDR7 : 0y0
+0x003 Instrumented : 0y0
+0x003 Reserved2 : 0y0000
+0x003 UmsScheduled : 0y0
+0x003 UmsPrimary : 0y0
+0x003 DpcActive : 0 ''
+0x000 Lock : 0n262144
+0x004 SignalState : 0n0
+0x008 WaitListHead : _LIST_ENTRY [ 0x877f40f0 - 0x877f40f0 ]
从以前的调查中,我还记得,如果+0x003 DpcActive
为1,这将意味着我们会等待一些硬件操作将其设置为0.但是在这种情况下它是0.
所以现在,我只是不知道这个NotificationEvent正在等待什么。 有什么想法?
尝试获取更完整的用户堆栈跟踪以查看GetOverlappedResult()的调用情况。试试'.process/p/r 87950030; .thread/p/r 877f4030; kb'这是否显示更多堆栈帧到用户堆栈? –
我删除了additinal stackframes,从我们的产品调用。调用':: CancelIo(port)后调用GetOverlappedResult; '和':: PurgeComm(端口,PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);'等待并保证操作完成。 Msdn表示,这两项操作在被调用后不能保证完成。 –
你打电话'GetOverlappedResult()'之前确保'CancelIo()'返回TRUE?如果'CancelIo()'返回false,那么没有I/O被取消,因此'GetOverlappedResult(...,BWAIT = TRUE)'*可能*不会再回来。我说*可能*,因为I/O可能在您调用'CancelIo()'之前完成。 –