2016-04-18 20 views
3

ich einen Prozess bin Debuggen, die wie eingefroren:eine NotificationEvent in Kernel Debug (Windows) Debuggen

  • ich die Ursache vermuten, dass das Gewinde unten THREAD 877f4030 Cid 0568.0fb8 ist, die auf dem Benutzer-Modus Aufruf an GetOverlappedResult stecken .

Ich habe den Dump mit kd.exe geöffnet.

Nämlich, ich bin daran interessiert, mehr über die NotificationEvent zu wissen, die offensichtlich nie unseren Thread freigibt.

Im Thread info haben wir:

879f6fdc NotificationEvent 

In welcher Art soll ich werfen Adresse 879f6fdc? oder in welchem ​​Strukturfeld sollte ich danach suchen, um zu verstehen, oder was ist ein Hinweis darauf, was die Situation blockiert?

Soweit die Thread Infos gehen, listet dieser Thread derzeit keine IRP auf, die in unerwünschtem oder unfertigem Zustand wären.


Below gesamte Thema Information für den entsprechenden Thread:

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]) 

Was ist der richtige Weg ist, welches Ereignis oder Synchronisations-Mechanismus zu gehen und wissen, Verwerfungen?


einige Befehle auf der NotificationEvent Adresse:

0: kd> !object 879f6fdc 
879f6fdc: Not a valid object (ObjectType invalid) 

0: kd> dt nt!_KEVENT 879f6fdc 
    +0x000 Header   : _DISPATCHER_HEADER 

und dann:

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 ] 

aus einer früheren Untersuchung, dass ich erinnere mich, wenn +0x003 DpcActive 1 war, es wir würden uns bedeuten würde, warten auf einige Hardware-Betrieb, um es auf 0 zu setzen. Aber in diesem Fall ist es 0.

Jetzt weiß ich einfach nicht, worauf dieses NotificationEvent wartet. Irgendeine Idee?

+0

Versuchen Sie, einen vollständigeren Stack-Trace des Benutzers zu erhalten, um zu sehen, was GetOverlappedResult() aufruft. Probieren Sie '.process/p/r 87950030; .thread/p/r 877f4030; kb 'Zeigt das mehr Stack-Frames in den User-Stack? –

+0

Ich entfernte die zusätzlichen Stackframes und rief von unserem Produkt. Wir rufen GetOverlappedResult nach Aufruf von ':: CancelIo (port); 'und' :: PurgeComm (Port, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR); 'um zu warten und zu garantieren, dass die Operationen beendet sind. Das Msdn gibt an, dass diese zwei Vorgänge nicht garantiert werden, nachdem sie aufgerufen werden. –

+0

Stellen Sie sicher, dass 'CancelIo()' TRUE zurückgibt, bevor'GeOverlappedResult() 'aufgerufen wird? Wenn 'CancelIo()' FALSE zurückgibt, wurde kein I/O abgebrochen und daher kann 'GetOverlappedResult (..., bWait = TRUE)' * * * niemals zurückkehren. Ich sage * kann *, weil die E/A möglicherweise kurz vor dem Aufruf von 'CancelIo()' abgeschlossen wurde. –

Antwort

1

Ereignisse warten nicht, Threads tun. NotificationEvents werden von jedem signalisiert, der die Operation ausführen würde und dann den Kellnern den Abschluß der Operation mitteilen. Mit anderen Worten, Ihr Stack ist ein Beispiel für ein Async-IO, bei dem wir eine überlappende Struktur mit einem hEvent-Set übergeben. Referenz https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342(v=vs.85).aspx

Sie sollten die Quelle, die diese IO eingeplant hat, oder den IO-Typ, auf den wir warten, überprüfen, anstatt das Ereignis auszugeben. Das Ereignis wird signalisiert, wenn der Vorgang abgeschlossen ist.