2016-04-18 57 views
3

我调试一个过程,就像是冷冻:调试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正在等待什么。 有什么想法?

+0

尝试获取更完整的用户堆栈跟踪以查看GetOverlappedResult()的调用情况。试试'.process/p/r 87950030; .thread/p/r 877f4030; kb'这是否显示更多堆栈帧到用户堆栈? –

+0

我删除了additinal stackframes,从我们的产品调用。调用':: CancelIo(port)后调用GetOverlappedResult; '和':: PurgeComm(端口,PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);'等待并保证操作完成。 Msdn表示,这两项操作在被调用后不能保证完成。 –

+0

你打电话'GetOverlappedResult()'之前确保'CancelIo()'返回TRUE?如果'CancelIo()'返回false,那么没有I/O被取消,因此'GetOverlappedResult(...,BWAIT = TRUE)'*可能*不会再回来。我说*可能*,因为I/O可能在您调用'CancelIo()'之前完成。 –

回答

1

事件不会等待,线程做。通知事件由任何执行操作的人发出信号,然后通知服务员完成操作。换句话说,你的栈是一个异步IO的例子,我们在这里传递一个带有hEvent集合的重叠结构。参考https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx

您应该检查已安排此IO的来源或我们正在等待的IO类型,而不是倾出事件。操作完成后,该事件将发出信号。