.NET Exceptions: Quick WinDbg/SOS tip on how to dump all the .NET exceptions on the heap
Since a .net exception is a .NET object like any other, it gets stored on the GC heap when you (or some code you call) calls new XXException().
This means that if you have a memory dump of a process you can dump out all the recent exceptions that have occurred, or rather all exceptions that have not yet been garbage collected, which will give you a good feel for what exceptions occurred recently.
Doing this is pretty easy if you have sos loaded (.loadby sos mscorwks) in windbg
0:015> !dumpheap -type Exception
------------------------------
Heap 0
Address MT Size
02ea6b0c 79330a80 72
02ea75f0 7930eab4 76
…
06f57aa4 7930eab4 76
06f5829c 7930eab4 76
06f58a94 7930eab4 76
06f5928c 7930eab4 76
06f59a84 7930eab4 76
06f5a27c 7930eab4 76
06f5aa74 7930eab4 76
06f5b26c 7930eab4 76
06f5ba64 7930eab4 76
06f5c25c 7930eab4 76
06f5ca54 7930eab4 76
06f5d24c 7930eab4 76
total 319 objects
------------------------------
total 656 objects
Statistics:
MT Count TotalSize Class Name
79333dc0 1 12 System.Text.DecoderExceptionFallback
79333d7c 1 12 System.Text.EncoderExceptionFallback
793172f8 2 64 System.UnhandledExceptionEventHandler
79330c30 1 72 System.ExecutionEngineException
79330ba0 1 72 System.StackOverflowException
79330b10 1 72 System.OutOfMemoryException
79330a80 1 72 System.Exception
79330cc0 2 144 System.Threading.ThreadAbortException
7930eab4 646 49096 System.IO.DirectoryNotFoundException
Total 656 objects
To dump information about a specific exception you can use !pe 02ea6b0c for example which will show you the stack, exception name etc.
The problem is that you have to do this for all the exceptions which can become pretty tedious if there are many of them, so to speed up the process you can use the .foreach command to automate the process
.foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe ${ex} }
This will go through all objects on the heap, where the typename contains the word exception and print them out with !pe (short for !PrintException)
Note that this will also include items that are not really exceptions like the System.Text.DecoderExceptionFallback, but since those are not exceptions it will just try to print them out but fail, so you can ignore those.
The output looks like this:
0:015> .foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe ${ex} }
********************************
Exception object: 02ea6b0c
Exception type: System.Exception
Message: The email entered is not a valid email address
InnerException: <none>
StackTrace (generated):
SP IP Function
024AF2C8 0FE3125E App_Code_da2s7oyo!BuggyMail.IsValidEmailAddress(System.String)+0x76
024AF2E8 0FE31192 App_Code_da2s7oyo!BuggyMail.SendEmail(System.String, System.String)+0x4a
StackTraceString: <none>
HResult: 80131500
There are nested exceptions on this thread. Run with -nested for details
********************************
Exception object: 02ea75f0
Exception type: System.IO.DirectoryNotFoundException
Message: Could not find a part of the path 'c:idontexistlog.txt'.
InnerException: <none>
StackTrace (generated):
SP IP Function
024AF044 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2
024AF0A0 792EB22B mscorlib_ni!System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)+0x48b
024AF198 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42
024AF1C0 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f
024AF1D4 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b
024AF1F4 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f
024AF204 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d
StackTraceString: <none>
HResult: 80070003
There are nested exceptions on this thread. Run with -nested for details
********************************
Exception object: 02ea7de8
Exception type: System.IO.DirectoryNotFoundException
Message: Could not find a part of the path 'c:idontexistlog.txt'.
InnerException: <none>
StackTrace (generated):
SP IP Function
024AEF60 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2
024AEFBC 792EB22B mscorlib_ni!System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean)+0x48b
024AF0B4 792EA882 mscorlib_ni!System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions)+0x42
024AF0DC 7927783F mscorlib_ni!System.IO.StreamWriter.CreateFile(System.String, Boolean)+0x3f
024AF0F0 792777DB mscorlib_ni!System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32)+0x3b
024AF110 797EE19F mscorlib_ni!System.IO.StreamWriter..ctor(System.String)+0x1f
024AF120 0FE31325 App_Code_da2s7oyo!Utility.WriteToLog(System.String, System.String)+0x5d
StackTraceString: <none>
HResult: 80070003
There are nested exceptions on this thread. Run with -nested for details
If you also want it to print out the nested exceptions you can just change the command a little bit to say
.foreach (ex {!dumpheap -type Exception -short}){.echo "********************************";!pe –nested ${ex} }
A couple of related posts:
Are you aware that you have thrown over 40,000 exceptions in the last 3 hours?
.Net exceptions - Tracking down where in the code the exceptions occurred
Questions about .net Exceptions
ASP.NET 2.0 Crash case study: Unhandled exceptions
Laters,
Tess
Comments
Anonymous
April 16, 2009
PingBack from http://microsoft-sharepoint.simplynetdev.com/net-exceptions-quick-windbgsos-tip-on-how-to-dump-all-the-net-exceptions-on-the-heap/Anonymous
April 16, 2009
Since a .net exception is a .NET object like any other, it gets stored on the GC heap when you (or someAnonymous
April 16, 2009
<OFFTOPICK> Hi Tess, in http://blogs.msdn.com/tess/archive/2006/02/15/net-memory-leak-xmlserializing-your-way-to-a-memory-leak.aspx you say "The only way to get rid of assemblies in 1.0 and 1.1 is to unload the app domain in which it resides." Is there another way to unload an assembly in 2.0? Thanks </OFFTOPICK>Anonymous
April 17, 2009
Interesting Finds: April 17, 2009Anonymous
April 19, 2009
John, no, you still need to unload the appdomain in 2.0Anonymous
April 20, 2009
Hi Tess. Could you do a comprehensive post on how to trigger a dump any time a .Net Exception gets thrown, or how to force a dump when a specific .Net exception gets thrown.Anonymous
April 20, 2009
sure, with debug diag, use this, but choose CLR (.NET) Exception rather than the custom exception i used, and specify System.NullReferenceException or whichever exception you want to capture. Or, if you can't install debug diag for some reason, you can use the config files available in this post. http://blogs.msdn.com/tess/archive/2005/11/30/are-you-aware-that-you-have-thrown-over-40-000-exceptions-in-the-last-3-hours.aspx#9557706Anonymous
April 21, 2009
My latest in a series of the weekly, or more often, summary of interesting links I come across related to Visual Studio. Ben Scheirman wrote up a walk-through of exporting Visual Studio solutions with SolutionFactory . The Web Developer Tools Team postedAnonymous
April 21, 2009
Web 7WaystoQuicklyRateWebsiteQuality HowtodetectIE8usingJavaScript(Clientside) S...Anonymous
April 28, 2009
I recently got an email with the following question: “Can you give me some very helpful hints with thisAnonymous
February 20, 2013
Hi Tess, awesome blog. It really helped me quite a lot already. But I am stuck now. Maybe you can give me a hint what I am doing wrong. I have a crash dump from a customer and after "!dumpheap -type Exception" I see several exceptions. But when I try to find to print the exceptions the stack trace does not show :( The output is similar to this one: Exception object: 01d0106c Exception type: System.StackOverflowException Message: <none> InnerException: <none> StackTrace (generated): <none> StackTraceString: <none> HResult: 800703e9 MichaelAnonymous
March 17, 2014
Hi tess, In the call stack we see 024AEF60 792741F2 mscorlib_ni!System.IO.__Error.WinIOError(Int32, System.String)+0xc2 What does 0xc2 refer to ? Can we get some info form the ildasm ?Anonymous
August 19, 2014
Hi Tess. This really helped . Thanks !Anonymous
October 23, 2014
using the !heap –s command i find that External fragmentation 31 % (42 free blocks). what winDBG command should i use to find out what caused the fragmentation please help me in finding the reasons for this Fragmentation.