title: Inspect Managed Timer Information Using WinDbg
body: <p>I have a 32-bit memory dump from a .NET 2.0.50727.6421 process that has stopped working correctly.  Some of its work is driven from a System.Threading.Timer.  The timer is supposed to trigger some processing.</p>
  
  <p>I am thinking the timer may be stopped, but I cannot figure out how to see this from the memory dump.</p>
  
  <p><strong>How can I tell the status of a .NET 2.0 System.Threading.Timer from a memory dump?</strong></p>
  
  <p>I have dumped the timer object.  Inside, there is a TimerBase object:</p>
  
  <pre><code>0:000&gt; !do 0204f72c 
  Name: System.Threading.Timer
  MethodTable: 74037344
  EEClass: 73e04230
  Size: 16(0x10) bytes
   (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
  Fields:
        MT    Field   Offset                 Type VT     Attr    Value Name
  74050924  400018a        4        System.Object  0 instance 00000000 __identity
  740373cc  4000687        8 ...reading.TimerBase  0 instance 0204f73c timerBase
  </code></pre>
  
  <p>I have dumped the TimerBase object, too.  There is a handle inside:</p>
  
  <pre><code>0:000&gt; !do 0204f73c 
  Name: System.Threading.TimerBase
  MethodTable: 740373cc
  EEClass: 73e699dc
  Size: 24(0x18) bytes
   (C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
  Fields:
        MT    Field   Offset                 Type VT     Attr    Value Name
  740535d0  4000682        4        System.IntPtr  1 instance  52b0508 timerHandle
  740535d0  4000683        8        System.IntPtr  1 instance  146f798 delegateInfo
  74052f54  4000684        c         System.Int32  1 instance        0 timerDeleted
  74052f54  4000685       10         System.Int32  1 instance        0 m_lock
  </code></pre>
  
  <p>I'm not sure how to inspect the timerHandle.  I can look at the raw memory, but this doesn't tell me much:</p>
  
  <pre><code>0:000&gt; dd 52b0508 
  052b0508  01465ae8 014b2fe0 008632fd 74a498c9
  052b0518  0146f798 00001770 00000000 00000003
  052b0528  00000001 ffffffff ffffffff 00000000
  052b0538  00000000 00000000 00000000 00000000
  052b0548  3980d87d 8a002250 00440050 00430049
  052b0558  0072006f 004c0065 00430049 006e006f
  052b0568  00690066 002e0067 006d0058 0053006c
  052b0578  00720065 00610069 0069006c 0065007a
  </code></pre>
  
  <p>I am not sure what the handle is pointing to.  I tried dumping it as _KTIMER object, but I don't know enough to see if this is the right kind of object, and if it is, what kind of thing it is:</p>
  
  <pre><code>0:000&gt; dt -r _KTIMER 52b0508 
  ntdll!_KTIMER
     +0x000 Header           : _DISPATCHER_HEADER
        +0x000 Type             : 0xe8 ''
        +0x001 TimerControlFlags : 0x5a 'Z'
        +0x001 Absolute         : 0y0
        +0x001 Wake             : 0y1
        +0x001 EncodedTolerableDelay : 0y010110 (0x16)
        +0x001 Abandoned        : 0x5a 'Z'
        +0x001 Signalling       : 0x5a 'Z'
        +0x002 ThreadControlFlags : 0x46 'F'
        +0x002 CycleProfiling   : 0y0
        +0x002 CounterProfiling : 0y1
        +0x002 GroupScheduling  : 0y1
        +0x002 AffinitySet      : 0y0
        +0x002 Reserved         : 0y0100
        +0x002 Hand             : 0x46 'F'
        +0x002 Size             : 0x46 'F'
        +0x003 TimerMiscFlags   : 0x1 ''
        +0x003 Index            : 0y1
        +0x003 Processor        : 0y00000 (0)
        +0x003 Inserted         : 0y0
        +0x003 Expired          : 0y0
        +0x003 DebugActive      : 0x1 ''
        +0x003 DpcActive        : 0x1 ''
        +0x000 Lock             : 0n21388008
        +0x000 LockNV           : 0n21388008
        +0x004 SignalState      : 0n21704672
        +0x008 WaitListHead     : _LIST_ENTRY [ 0x8632fd - 0x74a498c9 ]
           +0x000 Flink            : 0x008632fd _LIST_ENTRY
           +0x004 Blink            : 0x74a498c9 _LIST_ENTRY [ 0x6aec8b55 - 0xc75ff01 ]
     +0x010 DueTime          : _ULARGE_INTEGER 0x00001770`0146f798
        +0x000 LowPart          : 0x146f798
        +0x004 HighPart         : 0x1770
        +0x000 u                : &lt;unnamed-tag&gt;
           +0x000 LowPart          : 0x146f798
           +0x004 HighPart         : 0x1770
        +0x000 QuadPart         : 0x00001770`0146f798
     +0x018 TimerListEntry   : _LIST_ENTRY [ 0x0 - 0x3 ]
        +0x000 Flink            : (null) 
        +0x004 Blink            : 0x00000003 _LIST_ENTRY
           +0x000 Flink            : ???? 
           +0x004 Blink            : ???? 
     +0x020 Dpc              : 0x00000001 _KDPC
        +0x000 Type             : ??
        +0x001 Importance       : ??
        +0x002 Number           : ??
        +0x004 DpcListEntry     : _LIST_ENTRY
           +0x000 Flink            : ???? 
           +0x004 Blink            : ???? 
        +0x00c DeferredRoutine  : ???? 
        +0x010 DeferredContext  : ???? 
        +0x014 SystemArgument1  : ???? 
        +0x018 SystemArgument2  : ???? 
        +0x01c DpcData          : ???? 
     +0x024 Period           : 0xffffffff
  </code></pre>
  
  <p>Dumping the handle gives me an error:</p>
  
  <pre><code>0:000&gt; !handle 52b0508  f
  ERROR: !handle: extension exception 0x80004002.
      "Unable to read handle information"
  </code></pre>
  
  <p>I can see there are 9 managed threads:</p>
  
  <pre><code>0:000&gt; !threads
  ThreadCount: 148
  UnstartedThread: 0
  BackgroundThread: 8
  PendingThread: 0
  DeadThread: 139
  Hosted Runtime: no
                                        PreEmptive   GC Alloc           Lock
         ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
     0    1 2b5c 01448d50      a020 Enabled  00000000:00000000 01444930     0 MTA
     2    2  988 01456d40      b220 Enabled  00000000:00000000 01444930     0 MTA (Finalizer)
     3    4 1ae0 014a1f88   180b220 Enabled  14344f30:143467a0 01444930     0 MTA (Threadpool Worker)
     4    5 315c 014b6278    80a220 Enabled  00000000:00000000 01444930     0 MTA (Threadpool Completion Port)
     7    6 2034 05276be0   180b220 Enabled  00000000:00000000 01444930     0 MTA (Threadpool Worker)
     9    7 1b74 052c2618   200b220 Enabled  1414f654:14151330 01444930     1 MTA
  [snip]
    16   31 19bc 08195e00   180b220 Enabled  1436cb64:1436e7a0 01444930     0 MTA (Threadpool Worker)
    17   28 2208 08196da0   180b220 Enabled  00000000:00000000 01444930     0 MTA (Threadpool Worker)
    18   21 3290 08195248   880b220 Enabled  00000000:00000000 01444930     0 MTA (Threadpool Completion Port)
  [snip]
  </code></pre>
  
  <p>Thread 0 is the main thread of this Windows service.  Thread 2 is the GC finalizer thread.</p>
  
  <p>Thread 4:</p>
  
  <pre><code>0:004&gt; !dumpstack
  OS Thread Id: 0x315c (4)
  Current frame: ntdll!NtDelayExecution+0xc
  ChildEBP RetAddr  Caller,Callee
  04defb68 77a411f8 KERNELBASE!SleepEx+0x62, calling ntdll!NtDelayExecution
  04defba0 77a5b1e4 KERNELBASE!SleepEx+0x39, calling ntdll!RtlActivateActivationContextUnsafeFast
  04defbd0 74a48e23 mscorwks!ThreadpoolMgr::TimerThreadFire+0x6d, calling KERNELBASE!SleepEx
  04defc4c 74a48cd1 mscorwks!ThreadpoolMgr::TimerThreadStart+0x57, calling mscorwks!ThreadpoolMgr::TimerThreadFire
  04defc58 761186e3 kernel32!BaseThreadInitThunk+0xe
  04defc64 77c0aa29 ntdll!__RtlUserThreadStart+0x72
  04defca8 77c0a9fc ntdll!_RtlUserThreadStart+0x1b, calling ntdll!__RtlUserThreadStart
  </code></pre>
  
  <p>Thread 9 is a System.Net.Timer thread:</p>
  
  <pre><code>0:009&gt; !dso
  OS Thread Id: 0x1b74 (9)
  ESP/REG  Object   Name
  061bef84 1414f63c System.Object[]    (System.Threading.WaitHandle[])
  061bef98 1414f63c System.Object[]    (System.Threading.WaitHandle[])
  061befa8 1414f5fc System.Net.TimerThread+TimerNode
  061befac 024c83a4 System.Net.TimerThread+TimerQueue
  061befd8 1414f5a4 System.Net.TimerThread+TimerNode
  061beff8 024c812c System.Net.ConnectionPool
  061bf054 1414f63c System.Object[]    (System.Threading.WaitHandle[])
  061bf090 01ffde94 System.Object[]    (System.Threading.WaitHandle[])
  061bf09c 024c83a4 System.Net.TimerThread+TimerQueue
  061bf0bc 01ffdde8 System.Collections.Generic.LinkedList`1[[System.WeakReference, mscorlib]]
  061bf0c0 01ffddcc System.Collections.Generic.LinkedList`1[[System.WeakReference, mscorlib]]
  061bf120 02003cc0 System.Threading.ThreadHelper
  061bf378 02003cd4 System.Threading.ThreadStart
  </code></pre>