SOS Debugging with the CLR - Appendix A: Unexplained Exceptions on the Managed Heap

Before we get started here please be sure to read Jason Zander’s blog entry: SOS Debugging of the CLR, Part 1. This blog entry is intended for those people doing SOS debugging of managed applications.

Now that we have that covered…..

There’s a SOS command: !DumpHeap that dumps all of the objects in the managed heap. You may have noticed, or not, that typically you’ll always see the following three exceptions on the managed heap:

System.ExecutionEngineException

System.StackOverflowException

System.OutOfMemoryException

You may ask why you never have seen these exceptions before (at runtime or during post mortem debugging) or where do they come from? I’ll try to explain the origin of these mystifying exceptions:

Sometime during the initialization of your managed application by the CLR loader the exceptions mentioned above are thrown. You as the application launcher/developer never see these exceptions because they are caught by the CLR. The exceptions are still in the heap since they have not been handled. Consider a nested try catch block as follows:

                  try

                  {

                        // Do something

                  }

                  catch (Exception ex)

                  {

                        try

                        {

                              // Do some more

                        }

                        catch (Exception innerEx)

                        {

                              // You are here

                        }

                  }

When execution is at the “You are here” statement we have two exceptions that are in the heap. They won’t go away till we are out of the scope of this call stack path and the garbage collector has swept away our mess.

Now since I’m not a dev on the CLR team I can’t say exactly what we are doing when we generate these exceptions (We could make an educated guess by setting the debugger to break on all 1st chance exceptions of this type and look at the call stack.). What I can assume is that the loader is probably doing something akin to looking for certain execution options etc. but is not finding them and thus continues down an alternate path to accomplish what has been tasked to do Perhaps someone from the CLR team can post a comment about this if possible?

Now you do have to be careful because your application can also cause these types of exception. There are two ways (that I could think of off hand) that you can tell whether a given exception is one of these mysterious ones or not:

1. The callstack for the exception.   If there is a faulting callstack for the exception it warrants a closer look especially if the callstack contains method calls from your code. You can use the SOS command !Dumpobj to dump the exception and view it’s faulting callstack.

2. The exceptions above aren’t handled by the CLR.   If you see unmanaged exception handling (i.e. you see exception handling in Kernel32!RaiseException, or something similar) then we know that this exception was not handled by managed code and is therefore not one of the exceptions from above.

I hope this answers some questions and raises some good ones!