Unhandled exceptions


There are two kinds of threads executing inside managed code:  the ones we start in managed code and the ones that wander into the CLR. The ones that started in managed code include all calls to Thread.Start(), the managed threadpool threads, and the Finalizer thread(s).

For all the threads we start in managed code, the CLR has its own exception backstop and nothing will leak out to the OS unhandled exception filter.  We can call the AppDomain.UnhandledException event from this backstop.

For the ones that wander into managed code, we are registered on the OS unhandled exception filter so we can call the AppDomain.UnhandledException from there.  Of course, different unmanaged components are registered in a rather random order on the OS unhandled exception filter.  Some of them chain nicely. Others (like the VC6 filter) might decide to rip the process without chaining under certain circumstances.

So you are only completely assured of getting the AppDomain’s UnhandledException event on the managed threads.

Another subtlety is that you must register for this event in the Default AppDomain. That’s because – by the time the exception is unhandled – the thread has unwound out to the default AppDomain. That’s where all threads start executing and that’s where they eventually unwind to. This is an unfortunate restriction for some scenarios, but it’s not clear whether it will ever be relaxed.

Finally, the CLR has some default policy for which unhandled exceptions should terminate the process and which ones should be swallowed. Generally, unhandled exceptions on threadpool threads, the Finalizer thread(s) and similar “reusable” threads are swallowed. We simply terminate the current unit of work and proceed to the next one. Unhandled exceptions on the main thread of a managed executable will terminate the process.

Nobody particularly likes the defaults that were chosen. But everyone seems to have conflicting opinions on what would have made better defaults. And, at this point, nothing is likely to change. The UnhandledException event is there so that you can install your own policy. You can terminate the process, log the failure, trap to the debugger, swallow the exception or any other behavior.

Comments (11)

  1. aileen says:

    keep showing up on my pc when turn on

  2. aileen says:

    keep showing up on my pc when turn on

  3. .. the entry seem to imply that UnhandledException handle can be used to choose whether or not the errot is swollawed. This does not seem to be the case to me. The best you can hope to do is test if the application will termiate then restart if it is going to. Also the application always pops up an standard error box to inform the user an error has occured, there seem to be no way to suppress this.

    Or am I missing something?

  4. Chris Brumme says:

    It turns out that I’m the only person on our team who remembers the design I described in the above post. In other words, I must have imagined parts of it.

    You are correct that in V1 & V1.1, there is no way to swallow an exception via the UnhandledException event, if that exception is going to terminate the process. In that sense, the event is strictly a notification.

    You can still do the reverse. If an exception would be swallowed, you can use the UnhandledException event to terminate the process via System.Environment.Exit or some other technique.

    In a future version, we will give the host better control over how unhandled exceptions should be treated. But that’s no excuse for my mistakes in the above post.

  5. Thanks for getting back so quickly … actaully I’ve been playing with it a bit more and have a few further comments.

    I defintly want to use AppDomain.UnhandleException from a standard winforms app to implement some last chance error recovery. Trouble is the event seem a little flakey, I get different behavior depending on whether I’m debugging thorough visual studio or not.

    If it is in debug mode then unhandled exception will be caught by the event and the application will decided that the error is faltal and termiate the event.

    If the app is not in run from inside the debugger (but still a debug build) then a standard .NET error box will be shown asking if you want to continue or quit. If you continue then the app will recover reasonably well, if you quit it closes down, but either way the AppDomain.UnhandledException will not fire.

    Ideally what I’d like to do is suppress the standard error page, show my own custom error page and offer the user the chance to restart the app if it is going to terminate. But I’d settle from any hints or tips that offer me a little consistancy. Since I know whether the app is going to terminate or not it would be reasonable easy to kick of a new process using System.Diagnostics.Process, but only if the event actually fires!

    Thanks

  6. Actual there seems to be on way to turn off the "An unhandled exception …" digaol box in a winforms app. In this makes the AppDomain.UnhandledException event pretty useless in winforms app as it never get’s fired when the code is running outside the debugger.

    Went to huge efforts trying to find out how to turn off the dialog, then found out there’s very easy whay round it. Just use the System.Windows.Form.Application.ThreadException event instread.

Skip to main content