Assuming you already have WinDbg installed (X86 bit for your 32 bit applications, and the appropriate 64 edition for your 64 bit applications) , after startup in administration mode, you’ll want to:
1) Attach to your application process or run directly from WinDbg
2) For .Net 4.0 and above run .loadby sos clr or .loadby sos mscorwks for .Net 2.0
3) Update your symbol path so you have all the debug information that you’ll need e.g. ” *srv*c:\symbols*http://msdl.microsoft.com/downloads/symbols* “. You’ll also want to browse and add the location of the pdb files for you application.
4) Just like the VS debugger, press F5 to resume execution and CTRL+BREAK to break at any time.
5) In WinDbg, run !analyze -v (to force a load of the symbols – you’ll only need to do this the first time)
6) At any point in time when you’re at a break point you can
- View the CLR stack with !CLRstack
- View the managed threads with !Threads
- View combined managed and unmanaged call stack with !dumpstack
- View unmanaged code stack kL
Managed memory leak
- For a snapshot of managed memory type information run !DumpHeap -stat
- For managed memory information for a specific type run !DumpHeap -type <Type> e.g. Type = System.Reflection.RuntimeMethodInfo
- For further details check Rico Mariani’s Tracking down managed memory leaks article
- For heap information on a particular type of Exception run !DumpHeap -type Exception
- To break on all CLR exceptions run sxe clr
- To view the last thrown exception run !pe
- Turn on handle tracing with !htrace -enable
- Check handles with !handles
- Check specific handle stats with !handles <address>
For further details check Toby Opferman’s Handle leaks article
- For stats on GCHandles run !GCHandles
- For stats on what could potentially be a GCHandle leak, run !GCHandleLeaks
For further details check Alejandro Campos Magencio’s Managed Debugging with WinDbg article
Out of memory exceptions might also indicate memory fragmentation.
- !finalizequeue – to get details on the finalization queue and compare two results to see if there are any glaring increases in the objects. For example a huge jump in generation 2 objects but 0 objects ready to be finalized.
- After that you’ll want to look into the object that’s in the finalization queue using !do <address>. You can obtain the object addresses by listing out the dwords (using dd <starting address> <ending address>). For example, using the ending address of the 2nd generation minus the size of the object in question as the starting address, and the end of the 2nd generation as the ending address). For more details on this visit Shreous
- !gcroot -nostacks <object memory address> – To see the references for the object in question
Finally for a list of the extension commands: SOS Debugging Extensions.