Unhandled Exception after moving to .NET 4

in case this helps anyone out there (or myself, in the future!)

after moving a project to .NET4, you suddenly start seeing the unhandled exception dialog, shown by Windows, which prompts the user to try to debug the application (if there is a debugger such as Visual Studio installed).

Possible Reason:
- the program had a non-CLR unhandled exception all along, which was being passed to a .NET exception handler, and then 'swallowed' by that exception handler.

- as of .NET 4 by default, non-CLR exceptions are NOT caught by .NET code

- so, when the program is re-built with .NET4, and released, then the non-CLR exceptions that it was previously catching, are no longer being caught.  You then start to see the Windows system unhandled exception dialog.

- ideally, you would track down the non-CLR (i.e. C++!) exception, and fix it

- also, consider reviewing the exception handling code, to see why the exception was not noticed before

- however, the world in which we live, is not ideal, so we have some workarounds

Workaround #1: add legacyCorruptedState­­ExceptionsPolicy to the config file
Since my initial post, I found this article, which explains the changes Microsoft made to exception handling with .NET4:
http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

Microsoft have provided a way to maintain the legacy behaviour, without making code changes:
For compatibility reasons, the CLR team provided some ways to let you run your old code under the old behavior:
  • If you want to recompile your code created in the Microsoft .NET Framework 3.5 and run it in the .NET Framework 4.0 without having to update the source, you can add an entry in your application configuration file: legacyCorruptedState­­ExceptionsPolicy=true.
  • Assemblies compiled against the .NET Framework 3.5 or an earlier version of the runtime will be able to process corrupted state exceptions (in other words, maintain the old behavior) when running on the .NET Framework 4.0.
example:
insert this XML clip into app.config below the <configuration> element:

  <runtime>  

   <!-- .NET4 - enable legacy behaviour: if unmanaged (memory corrupted!) exception, then do NOT bomb out the application!
    instead .NET catch will kick in as normal (and we should log + exit ASAP)
    -->
   <legacyCorruptedStateExceptionsPolicy enabled="true" />
  </runtime>


Workaround #2: add Domain.UnhandledException event handler
When fixing this issue, I had not yet read about Workaround #1 above, and so I made some code changes:

- in my case, the exception is coming from a 3rd party DLL - we have no source code or debug libraries or support, so my fix was to restore the pre-.NET4 behaviour:

1. adding a Domain.UnhandledException event handler
2. marking the handler with these 2 attributes:
  HandleProcessCorruptedStateExceptions
  SecurityCritical

here is my VB.NET code, in case it helps anyone.
It is for a VB.NET program which is Windows Forms but does not actually display a form (I think it was a way of having an 'invisible console app').


   Public Sub main() 

       addHandlerForUnhandledExceptions() 

       ... 

       ... 

   End Sub 

   Private Sub addHandlerForUnhandledExceptions() 

     'in this program, on app exit, there is a spurious unhandled exception. 

     ' 

     'cause unknown - perhaps from the the third party DLL. 

     'impact: cosmetic only (as process is already exiting!) 

     ' 

     'adding this handler, to hide the exception from user. 

     'ref: http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx#Y1440 

     ' 

     'Win Forms app (!) so need to change a setting, in order to raise the event: 

     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException) 

     AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf handleUnhandledException 

   End Sub 

   '.NET4: will only pass non-managed exceptions to CLR handlers, if these 2 attributes are on the method. 

   ' 

   'I think this is why we were seeing the unhandled exception in the newer version of this program! (just because it was built with .NET 4!) 

   <HandleProcessCorruptedStateExceptionsAttribute()> 

   <SecurityCriticalAttribute()> 

   Private Sub handleUnhandledException(sender As Object, e As UnhandledExceptionEventArgs) 

     'do nothing (too late anyway, as app is exiting) 

     ' 

     'this handler is purely to try to hide the exception from users. 

     Diagnostics.Debug.Assert(False) 'will assert if in Debug build (intended for developer only!) 

     If e.IsTerminating Then 

       Environment.Exit(0) 'exit with success. this should prevent the default Windows unhandled exception handler from kicking in. 

     End If 

   End Sub  


note: depending on whether your program uses Windows Forms, and/or VB.NET then you may need to make changes to the above solution.

for more details, please see here:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx


there is also a nice article about exception usage here:
http://msdn.microsoft.com/en-us/magazine/dd419661.aspx

Comments