Search This Blog

Showing posts with label synchronization. Show all posts
Showing posts with label synchronization. Show all posts

Thursday, 30 October 2014

WinDbg : Debugging A Critical Section Based Dead Lock Scenario

WinDbg : Debugging A Critical Section Based Dead Lock Scenario


Dead locks can be very nasty and sometimes very hard to debug and root cause. This post is an attempt to walk you through one such scenario, where a critical section dead locks a thread. As with most of the previous posts, we will refrain from having source level help, that is, we will try and debug the faulty application without any source code and only symbols. 

Commands Used:

We start by attaching the debugger to he hung application, or we can also start the application inside the debugger if that is an alternative. In this example the name of the application is FaultyApp.Exe.

Once the application hangs, we start by taking a stack dump of all the threads currently running. Since this is an user land debugging scenario, the ~* command will give us the thread wise stack dump.

kd>~*kvn
0:004> ~*kvn

   0  Id: 6a0.5f8 Suspend: 1 Teb: 7efdd000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 0016f7b8 770315f7 00000003 0016f808 00000001 ntdll!NtWaitForMultipleObjects+0x15 (FPO: [5,0,0])
01 0016f854 76e719f8 0016f808 0016f87c 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100 (FPO: [Non-Fpo])
02 0016f89c 76e74200 00000003 7efde000 00000000 kernel32!WaitForMultipleObjectsExImplementation+0xe0 (FPO: [Non-Fpo])
03 0016f8b8 00bd11b5 00000003 0016f8d4 00000000 kernel32!WaitForMultipleObjects+0x18 (FPO: [Non-Fpo])
04 0016f8e4 00bd143d 00000001 00699318 00699368 FaultyApp!main+0x95 (FPO: [Non-Fpo]) (CONV: cdecl) 
05 0016f92c 76e7338a 7efde000 0016f978 77d79f72 FaultyApp!__tmainCRTStartup+0xfe (FPO: [Non-Fpo]) (CONV: cdecl) 
06 0016f938 77d79f72 7efde000 735ac1c9 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
07 0016f978 77d79f45 00bd1500 7efde000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
08 0016f990 00000000 00bd1500 7efde000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

   1  Id: 6a0.bc4 Suspend: 1 Teb: 7efda000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 0089feb4 77d78e44 00000048 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15 (FPO: [3,0,0])
01 0089ff18 77d78d28 00000000 00000000 00000000 ntdll!RtlpWaitOnCriticalSection+0x13e (FPO: [Non-Fpo])
02 0089ff40 00bd105c 6ce392e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])
03 0089ff54 76e7338a 00000000 0089ffa0 77d79f72 FaultyApp!FnThread1+0x2c (FPO: [Non-Fpo]) (CONV: cdecl) 
04 0089ff60 77d79f72 00000000 73c5c711 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
05 0089ffa0 77d79f45 00bd1005 00000000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
06 0089ffb8 00000000 00bd1005 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

   2  Id: 6a0.12fc Suspend: 1 Teb: 7efaf000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 00dffa50 77d78e44 00000048 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15 (FPO: [3,0,0])
01 00dffab4 77d78d28 00000000 00000000 00000000 ntdll!RtlpWaitOnCriticalSection+0x13e (FPO: [Non-Fpo])
02 00dffadc 00bd10fc 6ce392e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])
03 00dffaf0 76e7338a 00000000 00dffb3c 77d79f72 FaultyApp!FnThread3+0x2c (FPO: [Non-Fpo]) (CONV: cdecl) 
04 00dffafc 77d79f72 00000000 7393c38d 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
05 00dffb3c 77d79f45 00bd100f 00000000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
06 00dffb54 00000000 00bd100f 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

   3  Id: 6a0.11f0 Suspend: 1 Teb: 7efd7000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 00a6fa34 77d78e44 00000048 00000000 00000000 ntdll!ZwWaitForSingleObject+0x15 (FPO: [3,0,0])
01 00a6fa98 77d78d28 00000000 00000000 00000000 ntdll!RtlpWaitOnCriticalSection+0x13e (FPO: [Non-Fpo])
02 00a6fac0 00bd10ac 6ce392e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])
03 00a6fad4 76e7338a 00000000 00a6fb20 77d79f72 FaultyApp!FnThread2+0x2c (FPO: [Non-Fpo]) (CONV: cdecl) 
04 00a6fae0 77d79f72 00000000 73eac391 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
05 00a6fb20 77d79f45 00bd100a 00000000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
06 00a6fb38 00000000 00bd100a 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

#  4  Id: 6a0.11c8 Suspend: 1 Teb: 7efac000 Unfrozen
 # ChildEBP RetAddr  Args to Child              
00 00f0fd3c 77ddf926 73bcc5dd 00000000 00000000 ntdll!DbgBreakPoint (FPO: [0,0,0])
01 00f0fd6c 76e7338a 00000000 00f0fdb8 77d79f72 ntdll!DbgUiRemoteBreakin+0x3c (FPO: [Non-Fpo])
02 00f0fd78 77d79f72 00000000 73bcc509 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
03 00f0fdb8 77d79f45 77ddf8ea 00000000 ffffffff ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
04 00f0fdd0 00000000 77ddf8ea 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

The clue here is to look for the Windows API call RtlEnterCriticalSection. There might be  more than one thread in the stack making this function call, we can use any such thread.

Looking up on MSDN we see that the API is defined as follows:

NTSTATUS RtlEnterCriticalSection
 (
  RTL_CRITICAL_SECTION* crit
 )

In the above stack dump, we have several such threads, we take any one and them from the parameters list take the address of the RTL_CRITICAL_SECTION object pointer and type cast it to see the contents.

02 0089ff40 00bd105c 6ce392e0 00000000 00000000 ntdll!RtlEnterCriticalSection+0x150 (FPO: [Non-Fpo])

0:004> dt ntdll!_RTL_CRITICAL_SECTION 6ce392e0
   +0x000 DebugInfo        : 0x0069acf8 _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : 0n-14
   +0x008 RecursionCount   : 0n1
   +0x00c OwningThread     : 0x000005f8 Void
   +0x010 LockSemaphore    : 0x00000048 Void
   +0x014 SpinCount        : 0

We see that one of the members of this object gives us the Owning thread ID. 0x000005f8.

Lets try and find out more details about this thread. In user mode, the double tilde (~~) command will do it for us.

0:004> ~~[0x000005f8 ]
   0  Id: 6a0.5f8 Suspend: 1 Teb: 7efdd000 Unfrozen
      Start: FaultyApp!mainCRTStartup (00bd1500)
      Priority: 0  Priority class: 32  Affinity: ff

Ok so the thread offending is the main thread. This is good. Now we know where in the code of FaultyApp we need to start digging.

Lets start with disassembling the Main function. I will add the code in small sections explaining the relevant portions in between.

0:004> uF FaultyApp!main
FaultyApp!main:
00bd1120 55              push    ebp
00bd1121 8bec           mov    ebp,esp 

This is standard function prologue code, that we see in the above two lines.


00bd1123 83ec14        sub    esp,14h                                           

The above line is allocating space for local variables in the stack 

00bd1126 a11070bf00  mov   eax,dword ptr [FaultyApp!__security_cookie (00bf7010)]
00bd112b 33c5            xor     eax,ebp                                           


These two lines above is the code for stack guard.


00bd112d 8945fc          mov     dword ptr [ebp-4],eax
00bd1130 a100b0bf00   mov     eax,dword ptr [FaultyApp!_imp__g_CritSec (00bfb000)]
00bd1135 50                 push    eax
00bd1136 ff1534b0bf00 call    dword ptr [FaultyApp!_imp__InitializeCriticalSection (00bfb034)]    

the four lines above  is the code to initialize the critical section

00bd113c c745ec00000000  mov     dword ptr [ebp-14h],0
00bd1143 eb09                   jmp     FaultyApp!main+0x2e (00bd114e)

FaultyApp!main+0x25:
00bd1145 8b4dec          mov     ecx,dword ptr [ebp-14h]
00bd1148 83c101          add      ecx,1
00bd114b 894dec          mov     dword ptr [ebp-14h],ecx

FaultyApp!main+0x2e:
00bd114e 837dec03        cmp     dword ptr [ebp-14h],3                             

The line just above is comparing a local variable with a constant '3'

00bd1152 7333            jae     FaultyApp!main+0x67 (00bd1187)                  

If the comparison result is equal or greater than 3 then then jump out, else loop                                                    
FaultyApp!main+0x34:
00bd1154 6a00                    push    0
00bd1156 6a00                    push    0
00bd1158 6a00                    push    0
00bd115a 8b55ec                mov     edx,dword ptr [ebp-14h]
00bd115d 8b04950070bf00  mov     eax,dword ptr FaultyApp!pFnarry (00bf7000)[edx*4]   

This above sections seems to be initializing a function pointer array for thread functions.  We know this because of the call to CreateThread API a few lines below....
                                
00bd1164 50              push    eax
00bd1165 6a00            push    0
00bd1167 6a00            push    0
00bd1169 ff154cb0bf00    call    dword ptr [FaultyApp!_imp__CreateThread (00bfb04c)]

(the reader is encouraged to use MSDN to see the signature for CreateThread and all the parameters pushed into it inside this function to decrypt what all was passed)

00bd116f 8b4dec          mov     ecx,dword ptr [ebp-14h]
00bd1172 89448df0       mov     dword ptr [ebp+ecx*4-10h],eax
00bd1176 8b55ec          mov     edx,dword ptr [ebp-14h]
00bd1179 837c95f000    cmp     dword ptr [ebp+edx*4-10h],0
00bd117e 7505              jne     FaultyApp!main+0x65 (00bd1185)

FaultyApp!main+0x60:
00bd1180 83c8ff          or      eax,0FFFFFFFFh
00bd1183 eb32            jmp     FaultyApp!main+0x97 (00bd11b7)

FaultyApp!main+0x65:
00bd1185 ebbe            jmp     FaultyApp!main+0x25 (00bd1145)

FaultyApp!main+0x67:
00bd1187 a1b892bf00      mov     eax,dword ptr [FaultyApp!hStartThreads (00bf92b8)]
00bd118c 50                    push    eax
00bd118d ff1540b0bf00   call    dword ptr [FaultyApp!_imp__SetEvent (00bfb040)]
00bd1193 6a00                push    0
00bd1195 68f4010000      push    1F4h
00bd119a ff1544b0bf00   call    dword ptr [FaultyApp!_imp__SleepEx (00bfb044)]
00bd11a0 e885010000     call    FaultyApp!DllFunction (00bd132a)                      

After setting an event and sleeping for a while, it finally jumps to this function in the above line. DllFunction. We need to disassemble it to see where it leads us. I am not pasting the rest of the disassembly of the Main function as it is irrelevant to the rest of the context.

Lets start with the disassembly of DllFunction.


0:004> u FaultyApp!DllFunction
FaultyApp!DllFunction:
00bd132a ff2504b0bf00    jmp     dword ptr [FaultyApp!_imp__DllFunction (00bfb004)]
FaultyApp!__security_check_cookie:
00bd1330 3b0d1070bf00    cmp     ecx,dword ptr [FaultyApp!__security_cookie (00bf7010)]
00bd1336 7502                  jne     FaultyApp!__security_check_cookie+0xa (00bd133a)
00bd1338 f3c3                  rep ret
00bd133a e908020000       jmp     FaultyApp!__report_gsfailure (00bd1547)
FaultyApp!__tmainCRTStartup:
00bd133f 6a14                  push    14h
00bd1341 68d05dbf00       push    offset FaultyApp!__rtc_tzz+0x104 (00bf5dd0)
00bd1346 e8551a0000       call    FaultyApp!__SEH_prolog4 (00bd2da0)

Whats going on? This doesn't look like a function at all....so look closely at the first line copied again in the line below for your convenience...

00bd132a ff2504b0bf00    jmp     dword ptr [FaultyApp!_imp__DllFunction (00bfb004)]

This is actually a function pointer which is being de-referenced. So if it is a pointer, we need to see what it is pointing at:

0:004> dd 00bfb004
00bfb004  6ce11005 00000000 00000000 00000000
00bfb014  00000000 00000000 00000000 00000000
00bfb024  00000000 00000000 00000000 00000000
00bfb034  77d72c8a 77d622c0 77d62280 76e71691
00bfb044  76e71215 76e7324c 76e73495 76e741e8
00bfb054  76e75169 76e74a25 76e751fd 76e711c0
00bfb064  76e711a9 76e717b8 76e71420 77d8107b
00bfb074  77d79dd5 76e779d8 76e74a37 76e71222

Lets have a look at what is actually at this address.

0:004> u 6ce11005
FaultyDLL!ILT+0(_DllFunction):
6ce11005 e916000000      jmp     FaultyDLL!DllFunction (6ce11020)
FaultyDLL!ILT+5(_DllMain:
6ce1100a e931000000      jmp     FaultyDLL!DllMain (6ce11040)
6ce1100f cc              int     3
6ce11010 cc              int     3
6ce11011 cc              int     3
6ce11012 cc              int     3
6ce11013 cc              int     3
6ce11014 cc              int     3

It shows the name of a different module. FaultyDll. Looks like it is a DLL function being used, through the import address table (I know the name of the module has the word DLL in it, but that is not why i reached this conclusion).

Now lets disassemble the actual function the address of which we have been able to decipher.

0:004> u 6ce11020
FaultyDLL!DllFunction:
6ce11020 55                    push    ebp
6ce11021 8bec                mov     ebp,esp
6ce11023 68e092e36c      push    offset FaultyDLL!g_CritSec (6ce392e0)
6ce11028 ff1500b0e36c   call    dword ptr [FaultyDLL!_imp__EnterCriticalSection (6ce3b000)]
6ce1102e b801000000      mov     eax,1
6ce11033 5d                    pop     ebp
6ce11034 c3                    ret
6ce11035 cc                    int     3

It is a small function and what do we see in it? It enter's the critical section, but never leaves it. This is the bug!!

Main is shown as the owner of the critical section because it calls a faulty function which enters but never leaves the critical section.

Note: This is a very simple test application tailor made to produce the hang, real life scenarios might be much harder to debug and locate. But I do hope that this gives a starting point to folks wanting to chase such bugs!


Trivia : !cs command also gives info about all critical sections. !cs <address of crit> will dump info about that particular critical section. I deliberately avoided using it, as this exercise helps one understand such debugging scenarios in depth, rather than being dependent on a debugger extension.

Wednesday, 17 September 2014

WinDbg : !handle Command

WinDbg : !handle Command extension 


Handles are used everywhere in Windows. A handle in Windows is an opaque pointer. Almost every Windows API uses a handle as a reference to the internal object. WinDbg has the !handle extension command to help us find more information regarding handles.

Here is the output of !handle when run on a user mode crash dump. There are differences in the output of !handle when executed via user mode and via kernel mode, we will soon see these differences.


0:000> !handle


Handle 0000000000000004
  Type         Directory
Handle 0000000000000008
  Type         File
Handle 000000000000000c
  Type         Key
Handle 0000000000000010
  Type         Event
Handle 0000000000000014
  Type         ALPC Port
Handle 0000000000000024
  Type         Key
Handle 0000000000000030
  Type         WaitCompletionPacket
Handle 0000000000000034
  Type         IoCompletion
Handle 0000000000000038
  Type         TpWorkerFactory
Handle 000000000000003c
  Type         IRTimer
Handle 0000000000000040
  Type         WaitCompletionPacket
Handle 0000000000000044
  Type         IRTimer
Handle 0000000000000048
  Type         WaitCompletionPacket
Handle 000000000000004c
  Type        
<Output Snipped due to space constraints>
Handle 0000000000000bf8
  Type         Thread
377 Handles
Type                     Count
None                     26
Event                   74
Section                 5
File                     7
Directory               2
Mutant                   115
Semaphore               17
Key                     104
Thread                   11
IoCompletion             2
TpWorkerFactory         1
ALPC Port               9
WaitCompletionPacket     4


The handle command takes a few flags. Here is the output for handle 10 for each of the flags, 1, 2, 4, 8 and f(all flags enabled)

0:000> !handle 10 1
Handle 0000000000000010
  Type          Event

0:000> !handle 10 2
Handle 0000000000000010
  Attributes   0
  GrantedAccess 0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         Delete,ReadControl,WriteDac,WriteOwner,Synch
  HandleCount   2
  PointerCount 65537

0:000> !handle 10 4
Handle 0000000000000010
  Name         <none>

0:000> !handle 10 8
Handle 0000000000000010
  No object specific information available

0:000> !handle 10 f
Handle 0000000000000010
  Type         Event
  Attributes   0
  GrantedAccess 0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount   2
  PointerCount 65537
  Name         <none>
  Object specific information
    Event Type Auto Reset
    Event is Waiting

To get all information (0xf) about a particular type of handle (say for event objects) for all such events in the process (handle number 0 is all), we can use:

0:000> !handle 0 f event
Handle 0000000000000010
  Type         Event
  Attributes   0
  GrantedAccess 0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount   2
  PointerCount 65537
  Name         <none>
  Object specific information
    Event Type Auto Reset
    Event is Waiting
Handle 000000000000002c
  Type         Event
  Attributes   0
  GrantedAccess 0x1f0003:
         Delete,ReadControl,WriteDac,WriteOwner,Synch
         QueryState,ModifyState
  HandleCount   2
  PointerCount 65538
  Name         <none>
  Object specific information
    Event Type Auto Reset
    Event is Waiting

<Output Snipped to save space>

Handle 0000000000000afc
  Type         Event
  Attributes   0
  GrantedAccess 0x100003:
         Synch
         QueryState,ModifyState
  HandleCount   2
  PointerCount 65512
  Name         <none>
  Object specific information
    Event Type Auto Reset
    Event is Waiting
74 handles of type Event


The output and capabilities of the !handle in kernel mode is different. It is more powerful since the debugger actually has access to the Kernel objects required to fetch such information.

kd> !handle

PROCESS 851d1348  SessionId: 1  Cid: 08b4    Peb: 7ffd4000  ParentCid: 0138
    DirBase: 1eed3420  ObjectTable: 93d06750  HandleCount:  71.
    Image: NotMyfault.exe

Handle table at 93d06750 with 71 entries in use

0004: Object: 8b265108  GrantedAccess: 00000003 Entry: 93d26008
Object: 8b265108  Type: (839b7e90) Directory
    ObjectHeader: 8b2650f0 (new version)
        HandleCount: 29  PointerCount: 67
        Directory Object: 874010e8  Name: KnownDlls

        Hash Address  Type          Name
        ---- -------  ----          ----
         00  875dd678 Section       gdi32.dll
             8b2569f0 Section       kernelbase.dll
             87439a48 Section       IMAGEHLP.dll
         02  875fec88 Section       NORMALIZ.dll
         03  8d82ec58 Section       ole32.dll
             8847b3b8 Section       URLMON.dll
         04  874ff820 Section       USP10.dll
         05  8b252458 Section       DEVOBJ.dll
         06  8ca6d948 Section       SHELL32.dll
             8b250af0 Section       CFGMGR32.dll
             875c71a8 Section       WLDAP32.dll
         09  874e84d0 Section       user32.dll
         14  875de3f8 Section       MSASN1.dll
         16  875edf98 SymbolicLink  KnownDllPath
             8b21ed58 Section       COMCTL32.dll
         17  87580268 Section       CRYPT32.dll
             8b24bba8 Section       PSAPI.DLL
         18  885ffb68 Section       advapi32.dll
             87537178 Section       OLEAUT32.dll
         19  8b3f8478 Section       SHLWAPI.dll
             875d3b50 Section       IERTUTIL.dll
             8755ba30 Section       ntdll.dll
         20  8755b780 Section       WS2_32.dll
         21  8ca6d758 Section       LPK.dll
         22  874d3850 Section       sechost.dll
         23  8745c768 Section       COMDLG32.dll
         24  8ca63f10 Section       difxapi.dll
         25  8758b888 Section       Setupapi.dll
         26  874cc3c8 Section       MSCTF.dll
             8b3e3338 Section       WININET.dll
         27  875d8b48 Section       WINTRUST.dll
             875cdd30 Section       IMM32.dll
         28  8ca533c8 Section       MSVCRT.dll
         31  874d33c8 Section       rpcrt4.dll
             875358b0 Section       clbcatq.dll
         32  8ca593e0 Section       kernel32.dll
         35  875fedf0 Section       NSI.dll

0008: Object: 851d11c0  GrantedAccess: 00100020 Entry: 93d26010
Object: 851d11c0  Type: (83a287a8) File
    ObjectHeader: 851d11a8 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Users\Win7SP1x86-Debug\Desktop\Tools\Notmyfault\exe\Release {HarddiskVolume2}

000c: Object: 850bd518  GrantedAccess: 00100020 Entry: 93d26018
Object: 850bd518  Type: (83a287a8) File
    ObjectHeader: 850bd500 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2 {HarddiskVolume2}

0010: Object: 93cbdd48  GrantedAccess: 00020019 Entry: 93d26020
Object: 93cbdd48  Type: (83a2d388) Key
    ObjectHeader: 93cbdd30 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\NLS\SORTING\VERSIONS

0014: Object: 851d19e8  GrantedAccess: 001f0001 Entry: 93d26028
Object: 851d19e8  Type: (83a298f0) ALPC Port
    ObjectHeader: 851d19d0 (new version)
        HandleCount: 1  PointerCount: 3

0018: Object: 93cf3ec8  GrantedAccess: 00000001 Entry: 93d26030
Object: 93cf3ec8  Type: (83a2d388) Key
    ObjectHeader: 93cf3eb0 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\SESSION MANAGER

001c: Object: 850bd620  GrantedAccess: 00000804 Entry: 93d26038
Object: 850bd620  Type: (83a43f78) EtwRegistration
    ObjectHeader: 850bd608 (new version)
        HandleCount: 1  PointerCount: 1

0020: Object: 851cec08  GrantedAccess: 001f0003 (Protected) Entry: 93d26040
Object: 851cec08  Type: (83a33420) Event
    ObjectHeader: 851cebf0 (new version)
        HandleCount: 1  PointerCount: 2

0024: Object: 84ccffa8  GrantedAccess: 000f037f Entry: 93d26048
Object: 84ccffa8  Type: (83a28de8) WindowStation
    ObjectHeader: 84ccff90 (new version)
        HandleCount: 13  PointerCount: 24
        Directory Object: 95e31b38  Name: WinSta0

0028: Object: 84cd1d18  GrantedAccess: 000f01ff Entry: 93d26050
Object: 84cd1d18  Type: (83a28d20) Desktop
    ObjectHeader: 84cd1d00 (new version)
        HandleCount: 8  PointerCount: 476
        Directory Object: 00000000  Name: Default

002c: Object: 84ccffa8  GrantedAccess: 000f037f Entry: 93d26058
Object: 84ccffa8  Type: (83a28de8) WindowStation
    ObjectHeader: 84ccff90 (new version)
        HandleCount: 13  PointerCount: 24
        Directory Object: 95e31b38  Name: WinSta0

0030: Object: 90dbab80  GrantedAccess: 000f003f Entry: 93d26060
Object: 90dbab80  Type: (83a2d388) Key
    ObjectHeader: 90dbab68 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE

0034: Object: 851c79f8  GrantedAccess: 00000804 Entry: 93d26068
Object: 851c79f8  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851c79e0 (new version)
        HandleCount: 1  PointerCount: 1

0038: Object: 851c7990  GrantedAccess: 00000804 Entry: 93d26070
Object: 851c7990  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851c7978 (new version)
        HandleCount: 1  PointerCount: 1

003c: Object: 851c7928  GrantedAccess: 00000804 Entry: 93d26078
Object: 851c7928  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851c7910 (new version)
        HandleCount: 1  PointerCount: 1

0040: Object: 851d3cd8  GrantedAccess: 00000804 Entry: 93d26080
Object: 851d3cd8  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851d3cc0 (new version)
        HandleCount: 1  PointerCount: 1

0044: Object: 851cf428  GrantedAccess: 00000804 Entry: 93d26088
Object: 851cf428  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf410 (new version)
        HandleCount: 1  PointerCount: 1

0048: Object: 851cf490  GrantedAccess: 00000804 Entry: 93d26090
Object: 851cf490  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf478 (new version)
        HandleCount: 1  PointerCount: 1

004c: Object: 851cf3c0  GrantedAccess: 00000804 Entry: 93d26098
Object: 851cf3c0  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf3a8 (new version)
        HandleCount: 1  PointerCount: 1

0050: Object: 851cf358  GrantedAccess: 00000804 Entry: 93d260a0
Object: 851cf358  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf340 (new version)
        HandleCount: 1  PointerCount: 1

0054: Object: 851cf2f0  GrantedAccess: 00000804 Entry: 93d260a8
Object: 851cf2f0  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf2d8 (new version)
        HandleCount: 1  PointerCount: 1

0058: Object: 851cf288  GrantedAccess: 00000804 Entry: 93d260b0
Object: 851cf288  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cf270 (new version)
        HandleCount: 1  PointerCount: 1

005c: Object: 851cffd0  GrantedAccess: 00000804 Entry: 93d260b8
Object: 851cffd0  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cffb8 (new version)
        HandleCount: 1  PointerCount: 1

0060: Object: 851cff68  GrantedAccess: 00000804 Entry: 93d260c0
Object: 851cff68  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cff50 (new version)
        HandleCount: 1  PointerCount: 1

0064: Object: 851cff00  GrantedAccess: 00000804 Entry: 93d260c8
Object: 851cff00  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cfee8 (new version)
        HandleCount: 1  PointerCount: 1

0068: Object: 851cfea8  GrantedAccess: 001f0001 Entry: 93d260d0
Object: 851cfea8  Type: (83a25418) Mutant
    ObjectHeader: 851cfe90 (new version)
        HandleCount: 1  PointerCount: 1

006c: Object: 851d3b90  GrantedAccess: 001f0003 Entry: 93d260d8
Object: 851d3b90  Type: (83a33420) Event
    ObjectHeader: 851d3b78 (new version)
        HandleCount: 1  PointerCount: 1

0070: Object: 93d14c28  GrantedAccess: 00020019 Entry: 93d260e0
Object: 93d14c28  Type: (83a2d388) Key
    ObjectHeader: 93d14c10 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\NLS\LOCALE

0074: Object: 93c85638  GrantedAccess: 00020019 Entry: 93d260e8
Object: 93c85638  Type: (83a2d388) Key
    ObjectHeader: 93c85620 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\NLS\LOCALE\ALTERNATE SORTS

0078: Object: 8bbc5ab8  GrantedAccess: 00020019 Entry: 93d260f0
Object: 8bbc5ab8  Type: (83a2d388) Key
    ObjectHeader: 8bbc5aa0 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\MACHINE\SYSTEM\CONTROLSET001\CONTROL\NLS\LANGUAGE GROUPS

007c: Object: 851cfe48  GrantedAccess: 00000804 Entry: 93d260f8
Object: 851cfe48  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851cfe30 (new version)
        HandleCount: 1  PointerCount: 1

0080: Object: 850be990  GrantedAccess: 00000804 Entry: 93d26100
Object: 850be990  Type: (83a43f78) EtwRegistration
    ObjectHeader: 850be978 (new version)
        HandleCount: 1  PointerCount: 1

0084: Object: 851d3038  GrantedAccess: 001f0001 Entry: 93d26108
Object: 851d3038  Type: (83a298f0) ALPC Port
    ObjectHeader: 851d3020 (new version)
        HandleCount: 1  PointerCount: 1

0088: Object: 8bb01590  GrantedAccess: 00000004 Entry: 93d26110
Object: 8bb01590  Type: (83a31b50) Section
    ObjectHeader: 8bb01578 (new version)
        HandleCount: 6  PointerCount: 6

008c: Object: 851d31b8  GrantedAccess: 00000804 Entry: 93d26118
Object: 851d31b8  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851d31a0 (new version)
        HandleCount: 1  PointerCount: 1

0090: Object: 851d3220  GrantedAccess: 00000804 Entry: 93d26120
Object: 851d3220  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851d3208 (new version)
        HandleCount: 1  PointerCount: 1

0094: Object: 849c05a8  GrantedAccess: 00120089 Entry: 93d26128
Object: 849c05a8  Type: (83a287a8) File
    ObjectHeader: 849c0590 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Windows\System32\en-US\user32.dll.mui {HarddiskVolume2}

0098: Object: 851d9098  GrantedAccess: 001f0003 Entry: 93d26130
Object: 851d9098  Type: (83a33420) Event
    ObjectHeader: 851d9080 (new version)
        HandleCount: 1  PointerCount: 1

009c: Object: 95e2ed60  GrantedAccess: 0000000f Entry: 93d26138
Object: 95e2ed60  Type: (839b7e90) Directory
    ObjectHeader: 95e2ed48 (new version)
        HandleCount: 8  PointerCount: 43
        Directory Object: 95e2d298  Name: BaseNamedObjects

        Hash Address  Type          Name
        ---- -------  ----          ----
         00  95e2fc68 SymbolicLink  Local
             8506b5d8 Mutant        ZonesCacheCounterMutex
         01  850d3ab8 Mutant        ZonesLockedCacheCounterMutex
             8515d8b0 Mutant        AccessibilitySoundAgentRunning
             84f40ff0 Event         ThemesStartEvent
         02  95e2c428 Directory     Restricted
         03  84cd0298 Event         ScNetDrvMsg
         04  8e5479f0 Section       windows_shell_global_counters
         07  850f9580 Event         ShellDesktopSwitchEvent
         09  8513eb80 Event         MSCTF.AsmCacheReady.Default1
             84f53ea8 Event         ThemeLoadedEvent
         10  8513ec20 Event         MSCTF.CtfActivated.Default1
             90db9c98 Section       C:*ProgramData*Microsoft*Windows*Caches*{7CD55808-3D38-4DD5-90C9-62F0E6EE60D4}.2.ver0x0000000000000001.db
             90d58340 Section       C:*ProgramData*Microsoft*Windows*Caches*{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000007.db
         12  85145948 Mutant        MSCTF.CtfMonitorInstMutexDefault1
         13  84f96470 Event         ShellReadyEvent
             90d5eaa0 Section       C:*ProgramData*Microsoft*Windows*Caches*cversions.2.ro
         14  90d59c58 Section       C:*ProgramData*Microsoft*Windows*Caches*{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000002.db
         16  95e2d158 SymbolicLink  Global
         19  84d0e4d8 Event         WinSta0_DesktopSwitch
         20  848c5b18 Mutant        ZoneAttributeCacheCounterMutex
             84ccd208 Event         EventShutDownCSRSS
         21  8ba99b88 Section       windows_ie_global_counters
         22  84d79e10 Mutant        ALTTAB_RUNNING_MUTEX
         26  85100380 Event         MSCTF.CtfMonitorInitialized.Default1
         28  851450a8 Mutant        CicLoadWinStaWinSta0
             85182080 Mutant        _SHuassist.mtx
         29  849544e8 Mutant        ZonesCounterMutex
             85144700 Mutant        MSCTF.Asm.MutexDefault1
         30  95e1f100 SymbolicLink  Session
         31  8e551830 Section       UrlZonesSM_Win7SP1x86-Debug
         33  85141528 ALPC Port     Dwm-49D1-ApiPort-1BF9
             8e5ae7c8 Section       CTF.AsmListCache.FMPDefault1
         35  8513ebd0 Event         MSCTF.CtfDeactivated.Default1

00a0: Object: 851d1b90  GrantedAccess: 001f0003 Entry: 93d26140
Object: 851d1b90  Type: (83a33420) Event
    ObjectHeader: 851d1b78 (new version)
        HandleCount: 1  PointerCount: 1

00a4: Object: 851db930  GrantedAccess: 001f0003 Entry: 93d26148
Object: 851db930  Type: (83a33420) Event
    ObjectHeader: 851db918 (new version)
        HandleCount: 1  PointerCount: 1

00a8: Object: 851d2530  GrantedAccess: 00000804 Entry: 93d26150
Object: 851d2530  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851d2518 (new version)
        HandleCount: 1  PointerCount: 1

00ac: Object: 851d97d8  GrantedAccess: 00000804 Entry: 93d26158
Object: 851d97d8  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851d97c0 (new version)
        HandleCount: 1  PointerCount: 1

00b0: Object: 851c7df8  GrantedAccess: 001f0003 Entry: 93d26160
Object: 851c7df8  Type: (83a33420) Event
    ObjectHeader: 851c7de0 (new version)
        HandleCount: 1  PointerCount: 1

00b4: Object: 851d8d48  GrantedAccess: 001fffff Entry: 93d26168
Object: 851d8d48  Type: (839b78b0) Thread
    ObjectHeader: 851d8d30 (new version)
        HandleCount: 2  PointerCount: 4

00b8: Object: 851d96a0  GrantedAccess: 001f0001 Entry: 93d26170
Object: 851d96a0  Type: (83a298f0) ALPC Port
    ObjectHeader: 851d9688 (new version)
        HandleCount: 1  PointerCount: 1

00bc: Object: 852540f0  GrantedAccess: 0012019f Entry: 93d26178
Object: 852540f0  Type: (83a287a8) File
    ObjectHeader: 852540d8 (new version)
        HandleCount: 1  PointerCount: 3

00c0: Object: 8507f098  GrantedAccess: 001f0003 Entry: 93d26180
Object: 8507f098  Type: (83a28870) IoCompletion
    ObjectHeader: 8507f080 (new version)
        HandleCount: 1  PointerCount: 2

00c4: Object: 85255ee0  GrantedAccess: 000f00ff Entry: 93d26188
Object: 85255ee0  Type: (83a28c58) TpWorkerFactory
    ObjectHeader: 85255ec8 (new version)
        HandleCount: 1  PointerCount: 1

00c8: Object: 94078d00  GrantedAccess: 000f0003 Entry: 93d26190
Object: 94078d00  Type: (83a28eb0) KeyedEvent
    ObjectHeader: 94078ce8 (new version)
        HandleCount: 1  PointerCount: 1

00cc: Object: 850bfe38  GrantedAccess: 00100002 Entry: 93d26198
Object: 850bfe38  Type: (83a26350) Timer
    ObjectHeader: 850bfe20 (new version)
        HandleCount: 1  PointerCount: 2

00d0: Object: 850bfd70  GrantedAccess: 001f0003 Entry: 93d261a0
Object: 850bfd70  Type: (83a26350) Timer
    ObjectHeader: 850bfd58 (new version)
        HandleCount: 1  PointerCount: 2

00d4: Object: 850bfa88  GrantedAccess: 001fffff Entry: 93d261a8
Object: 850bfa88  Type: (839b78b0) Thread
    ObjectHeader: 850bfa70 (new version)
        HandleCount: 2  PointerCount: 3

00d8: Object: 850bfa88  GrantedAccess: 001fffff Entry: 93d261b0
Object: 850bfa88  Type: (839b78b0) Thread
    ObjectHeader: 850bfa70 (new version)
        HandleCount: 2  PointerCount: 3

00dc: Object: 851b1240  GrantedAccess: 001f0003 Entry: 93d261b8
Object: 851b1240  Type: (83a28870) IoCompletion
    ObjectHeader: 851b1228 (new version)
        HandleCount: 1  PointerCount: 2

00e0: Object: 850bf9e0  GrantedAccess: 000f00ff Entry: 93d261c0
Object: 850bf9e0  Type: (83a28c58) TpWorkerFactory
    ObjectHeader: 850bf9c8 (new version)
        HandleCount: 1  PointerCount: 1

00e4: Object: 850bf918  GrantedAccess: 00100002 Entry: 93d261c8
Object: 850bf918  Type: (83a26350) Timer
    ObjectHeader: 850bf900 (new version)
        HandleCount: 1  PointerCount: 2

00e8: Object: 850bf868  GrantedAccess: 00120089 Entry: 93d261d0
Object: 850bf868  Type: (83a287a8) File
    ObjectHeader: 850bf850 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Windows\Fonts\StaticCache.dat {HarddiskVolume2}

00ec: Object: 90d6b3b0  GrantedAccess: 000f0005 Entry: 93d261d8
Object: 90d6b3b0  Type: (83a31b50) Section
    ObjectHeader: 90d6b398 (new version)
        HandleCount: 1  PointerCount: 1

00f0: Object: 84d4c968  GrantedAccess: 001f0003 Entry: 93d261e0
Object: 84d4c968  Type: (83a33420) Event
    ObjectHeader: 84d4c950 (new version)
        HandleCount: 1  PointerCount: 1

00f4: Object: 851c8e88  GrantedAccess: 00000804 Entry: 93d261e8
Object: 851c8e88  Type: (83a43f78) EtwRegistration
    ObjectHeader: 851c8e70 (new version)
        HandleCount: 1  PointerCount: 1

00f8: Object: 84d50c78  GrantedAccess: 001f0003 Entry: 93d261f0
Object: 84d50c78  Type: (83a33420) Event
    ObjectHeader: 84d50c60 (new version)
        HandleCount: 1  PointerCount: 1

00fc: Object: 849fa258  GrantedAccess: 001f0003 Entry: 93d261f8
Object: 849fa258  Type: (83a33420) Event
    ObjectHeader: 849fa240 (new version)
        HandleCount: 1  PointerCount: 1

0100: Object: 84d70360  GrantedAccess: 001f0003 Entry: 93d26200
Object: 84d70360  Type: (83a33420) Event
    ObjectHeader: 84d70348 (new version)
        HandleCount: 1  PointerCount: 1

0104: Object: 851cc628  GrantedAccess: 001f0003 Entry: 93d26208
Object: 851cc628  Type: (83a33420) Event
    ObjectHeader: 851cc610 (new version)
        HandleCount: 1  PointerCount: 1

0108: Object: 8523bd38  GrantedAccess: 001f0003 Entry: 93d26210
Object: 8523bd38  Type: (83a33420) Event
    ObjectHeader: 8523bd20 (new version)
        HandleCount: 1  PointerCount: 1

010c: Object: 83a4c0f8  GrantedAccess: 001f0003 Entry: 93d26218
Object: 83a4c0f8  Type: (83a33420) Event
    ObjectHeader: 83a4c0e0 (new version)
        HandleCount: 1  PointerCount: 1

0110: Object: 851cf6d0  GrantedAccess: 001f0003 Entry: 93d26220
Object: 851cf6d0  Type: (83a33420) Event
    ObjectHeader: 851cf6b8 (new version)
        HandleCount: 1  PointerCount: 1

0114: Object: 85255318  GrantedAccess: 00100001 Entry: 93d26228
Object: 85255318  Type: (83a287a8) File
    ObjectHeader: 85255300 (new version)
        HandleCount: 1  PointerCount: 1

0118: Object: 93d12608  GrantedAccess: 000f003f Entry: 93d26230
Object: 93d12608  Type: (83a2d388) Key
    ObjectHeader: 93d125f0 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \REGISTRY\USER\S-1-5-21-4213196723-1351097745-788781942-1001

011c: Object: 8e5479f0  GrantedAccess: 00000006 Entry: 93d26238
Object: 8e5479f0  Type: (83a31b50) Section
    ObjectHeader: 8e5479d8 (new version)
        HandleCount: 3  PointerCount: 4
        Directory Object: 95e2ed60  Name: windows_shell_global_counters

As we see the object information and name is given out with a horde of other useful stuff. 

Thus we see that to debug handle leaks etc, it is perhaps more useful to have a full kernel dump instead of just a process dump.

For example, assuming that we want to find out all open file handles for the process 'system'. We can do that with these steps below:

kd> !process 0 0 system
PROCESS 839afbf8  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 87401ca0  HandleCount: 463.
    Image: System

kd> .process /p /r 839afbf8
Implicit process is now 839afbf8
Loading User Symbols

kd> !handle 0 7 839afbf8 File

Searching for handles of type File

PROCESS 839afbf8  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 87401ca0  HandleCount: 463.
    Image: System

Kernel handle table at 87401ca0 with 463 entries in use

0054: Object: 849133f0  GrantedAccess: 00120116 Entry: 874030a8
Object: 849133f0  Type: (83a287a8) File
    ObjectHeader: 849133d8 (new version)
        HandleCount: 1  PointerCount: 1

0060: Object: 84871940  GrantedAccess: 00100001 Entry: 874030c0
Object: 84871940  Type: (83a287a8) File
    ObjectHeader: 84871928 (new version)
        HandleCount: 1  PointerCount: 1

0064: Object: 84dc24d0  GrantedAccess: 0012008b Entry: 874030c8
Object: 84dc24d0  Type: (83a287a8) File
    ObjectHeader: 84dc24b8 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Windows\System32\wdi\LogFiles\WdiContextLog.etl.003 {HarddiskVolume2}

0070: Object: 84c0ef80  GrantedAccess: 0012019f Entry: 874030e0
Object: 84c0ef80  Type: (83a287a8) File
    ObjectHeader: 84c0ef68 (new version)
        HandleCount: 1  PointerCount: 2

0088: Object: 84c42788  GrantedAccess: 0012019f Entry: 87403110
Object: 84c42788  Type: (83a287a8) File
    ObjectHeader: 84c42770 (new version)
        HandleCount: 1  PointerCount: 2
        Directory Object: 00000000  Name: \$Extend\$RmMetadata\$TxfLog\$TxfLog.blf {HarddiskVolume1}

008c: Object: 84c30268  GrantedAccess: 0012019f (Inherit) Entry: 87403118
Object: 84c30268  Type: (83a287a8) File
    ObjectHeader: 84c30250 (new version)
        HandleCount: 1  PointerCount: 2
        Directory Object: 00000000  Name: TxfLog {clfs}

0090: Object: 84c30310  GrantedAccess: 0012019f Entry: 87403120
Object: 84c30310  Type: (83a287a8) File
    ObjectHeader: 84c302f8 (new version)
        HandleCount: 1  PointerCount: 2
        Directory Object: 00000000  Name: \$Extend\$RmMetadata\$TxfLog\$TxfLogContainer00000000000000000001 {HarddiskVolume1}

<Output snipped>


0140: Object: 847e7e98  GrantedAccess: 00020003 (Protected) Entry: 87403280
Object: 847e7e98  Type: (83a287a8) File
    ObjectHeader: 847e7e80 (new version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Windows\System32\config\SOFTWARE {HarddiskVolume2}


0728: free handle, Entry address 87403e50, Next Entry 00000744
0734: free handle, Entry address 87403e68, Next Entry 0000083c
0ffc: free handle, Entry address 91427ff8, Next Entry 00000000


<Output snipped>

I have deliberately snipped the output since it is very long. As we see, we have open handles for regular files, registry, transaction logs and what not.

We will revisit this topic again in a future post to see how this information can be extended to actually find which device is an IO bound to.


We can use the !object command to get even more useful information of the handle in question. Here is a link to a blog post which describes how the !object command works.