CLR 4.0: Corrupted State Exceptions

Note: This blog post transferred from my OLD BLOG and was originally posted in 2008.

image image

Thread Created by the CLR

Thread Created outside the CLR

Threads that can run managed code can be classified into two types.

  1. There are threads that are created by the CLR, and for such threads, the CLR controls the base (the starting frame) of the thread.
  2. There are also threads that are created outside the CLR but enter it at some later point to execute managed code; for such threads, the CLR does not control the thread base.
The CLR uses the following algorithm to trigger and handle thrown exceptions within the CLR Created Threads. After the CLR walks up the exception call stack, if the CLR can’t find a managed exception handler in Main, the exception will reach the native frame within the CLR where the thread started. In this frame, the CLR has established an exception filter that will apply the policy to swallow (blind catch) exceptions, if applicable. If the policy indicates not to swallow the exception ( default in .NET Framework 2.0 and later), the filter triggers the CLR’s unhandled exception processing.The Unhandled Exception Processing History in .Net

In the .NET Framework 1.0 and 1.1, unhandled exceptions on threads that were created within the CLR were swallowed at the thread base (the native function at which the thread started in the CLR).
Which is, the behavior we don’t want, since the CLR has no clue about the reason the exception was raised in the first place. Thus, swallowing such an exception, is a mistake since the extent of application or process state corruption cannot be determined. What if the exception was the kind that would indicate a corrupted process state such as Access Violation, for instance?

In the .NET Framework 2.0, this behavior was changed. Unhandled exceptions on threads created by the CLR are no longer swallowed. If the exception is not handled by any managed frame on the stack, the CLR will let it go unhandled to the OS after triggering the unhandled exception process. The unhandled exception, then, will result in an application crash.

And for backward compatibility with legacy application that built on top of CLR 1.0, CLR 2.0 provided a flag was that could be set in the application configuration file’s runtime section to have the old behavior of swallowing the unhandled exceptions:

 1: <configuration>
 2:   <runtime>
 3:     <legacyUnhandledExceptionPolicy enabled="true"/>
 4:   </runtime>
 5: </configuration>
image

Super Exceptions (New in CLR 4.0)

CLR 4.0 will not allow you anymore to catch exceptions that may corrupt the state of the current running process, the CLR 4.0 introduced this new concept of Corrupted State Exceptions (i like to think of those as Super Exceptions), those exceptions that could corrupt the state of the process and causing losing user data or weird application behaviors like:

  • Access Violation Exception
  • Invalid Memory Exception
  • etc ..

Those kind of exceptions is dangerous and the best scenario most of the time is to stop processing as quick as you can before you lose user important data or cause the application to behave in unexpected ways.

A sample scenario of when those exception could happen like the following scenario, if you try to run this sample code while you another process accessing “file.txt” you will got Access Violation Exception. In .Net 2.0 you can catch and swallow this kind of exceptions as in this code snippet; But this will not be the case anymore, which means that the catch statements will not be able anymore to see this Corrupted State Exceptions, and no matter what they will popup and stop the process of continuing its work.

 1: class Program
 2: {
 3:     static void Main(string[] args)
 4:     {
 5:         SaveFile("file.txt");
 6:         Console.ReadLine();
 7:     }
 8:
 9:     public static void SaveFile(string fileName)
 10:     {
 11:         try
 12:         {
 13:             FileStream fs = new FileStream(fileName, FileMode.Create);
 14:         }
 15:         catch (Exception ex)
 16:         {
 17:             Console.WriteLine("File open error");
 18:             throw new IOException();
 19:         }
 20:     }
 21: }

The CLR team knew that there are some rear circumstances that you will need to handle those Corrupted State ExceptionThe Super-Exception “, may be for doing some log routine but not to continue processing. So CLR 4.0 provide a new attribute called HandleProcessCorruptedStateExceptions, you can use to decorate the methods you want to use in doing some log routines or whatever notification scenarios about those super exceptions.

 1: [HandleProcessCorruptedStateExceptions]
 2: public static void HandleCorruptedStateException()
 3: {
 4:     // Write your Super-Exception Notification code here
 5:     // log, or Send Mail etc ..
 6: }
Also for backward compatibility purposes CLR 4.0 provides a new process wide compact switch you can easily set to have the old behavior of catching those Corrupted State Exceptions as in previous versions of CLR.
 1: <configuration>
 2:   <runtime>
 3:     <legacyCorruptedStateExceptionsPolicy enabled="true"/>
 4:   </runtime>
 5: </configuration>

Related Stuff:

  1. PDC 2008: PC49, Microsoft .NET Framework – CLR Futures (Video|PPTX).
  2. Unhandled Exception Processing In The CLR (Gaurav Khanna)
  3. CLR 4.0: Type Embedding
  4. CLR 4.0: New Enhancements in the Garbage Collection

Hope this Helps,

Ahmed