Post-mortem debugging of .NET applications using WinDbg

Debugging is a skill you learn under pressure, because you usually learn it when things are going awry with a particular application or service just gone live, and you are quite convinced it has no severe bugs. It is never a pleasure to encounter such bugs, because although they happen quite frequently in your production environment, they are particularly hard to reproduce in your development or test environment.

For managed applications, you can learn a new skill that will save you some face, it is called post-mortem debugging. WinDbg is a splendid tool. It can be used to debug any arbitrary running process, but it is a really useful tool for debugging memory dumps.

Process memory can be dumped quite easily using several ways:

  • You can use WinDbg. Install WinDbg, attach to a process, break on the required exception and then dump memory. Memory can be dumped from the command line or the file menu. From the command line, just type: .dump /ma filename.dmp. You need to have enough disk space because dmp files can be rather big.
  • On newer versions of Windows you can dump process memory using the Task Manager.

There are several other ways that are already documented elsewhere, but for most purposes the above should suffice.

Once you have the dump file, you can open it with WinDbg. There are several useful commands you can then execute to examine the process:

  • !runaway – shows thread times. This can be really useful to find badly behaved threads that are consuming much CPU.
  • !analyze -v – shows detailed information about the current exception.
  • !threads – shows a list of threads currently in execution.
  • !uniqstack – displays all stacks of all the threads of the current process. You can also see the stack trace of a single thread using the k commands.
  • ~ns – sets the thread with ID n as the current thread.

WinDbg is much more useful for debugging managed application with the following extensions in use:

  • SOS – This extension is distributed along with the .NET framework can be loaded using the following command: .loadby sos mscorwks or .loadby sos clr for .NET 4.
  • SOSEX – This has several useful additions to the core SOS extension. It must be loaded by using the .load command e.g. .load c:\sosex\sosex.dll.
  • Psscor2 – Has several useful commands, especially commands for debugging ASP.NET applications. Load it using the .load command e.g. .load c:\psscor2\x86\psscor2.dll.

The SOS extension has several useful commands. The ones that are used more frequently are:

  • !clrstack -p – prints the stack trace of the current thread. This only works for managed threads. If you have symbols for your assemblies, you can see some pretty detailed information in the stack trace.
  • !dumpheap – dumps the objects from the heap. You can dump objects of a specific type by using the -type option e.g. !dumpheap -type System.Threading.Thread. This can be really useful to list all objects and their addresses. By knowing the number of objects of a particular type in use you can debug typical resource exhaustion problems.
  • !do address – dumps information about the object at the address specified. Value of primitive fields of the object are displayed and other references can be further examined using this command.
  • !da – prints information about an array

The SOSEX extensions has the following commands that are particularly useful:

  • !refs – prints all objects that reference the object specified.
  • !dlk – searches for possible deadlocks.

The Psscor2 has one particularly useful command among several others, this command can come in handy when troubleshooting network related issues:

  • !PrintIPAddress – prints the IP address of the specified IPAddress instance.

This short post is meant to whet your appetite for post-mortem debugging and to point you in the right direction. Enjoy!


One thought on “Post-mortem debugging of .NET applications using WinDbg

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s