Recipe 5.10 Preventing Unhandled Exceptions
Problem
You need to make absolutely sure
that every exception thrown by your application is handled and that
no exception is bubbled up past the outermost exception handler.
Hackers often use these types of exceptions to aid in their analysis
of the vulnerabilities of an application.
Solution
Place try-catch or
try-catch-finally blocks in strategic places in
your application. In addition, use the exception event handler as a
final line of defense against unhandled exceptions.
Discussion
If an exception occurs and is not handled, it will cause your
application to shut down prematurely. This can leave data in an
unstable state, which may only be able to be rectified by manual
intervention-meaning that you could be spending a long night
cleaning up the data by hand. To minimize the damage, you can place
exception handlers in strategic locations throughout your code.
The most obvious location to place exception handling code is inside
of the Main method. The Main
method is the entry point to executables (files with an
.exe extension). Therefore, if any exceptions
occur inside your executable, the CLR starts looking for an exception
handler, starting at the location where the exception occurred. If
none are found, the CLR walks the stack until one is found; each
method on the stack is examined in turn to determine whether an
exception handler exists. If no exception handlers are found in the
final method in the stack, the exception is considered unhandled and
the application is terminated. In an executable, this final method is
the Main method.
In addition, or in place of using try-catch or
try-catch-finally blocks at the entry point of
your application, you can use the exception event handler to capture
unhandled exceptions. Note that Windows Forms applications provide
their own unhandled exception trap around exception handlers and
never raise the AppDomain level event. There are two steps to setting
up an exception event handler. The first is to create the actual
event handler. This is done as
follows:
static void LastChanceHandler(object sender, UnhandledExceptionEventArgs args)
{
try
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("Unhandled exception == " + e.ToString( ));
if (args.IsTerminating)
{
Console.WriteLine("The application is terminating");
}
else
{
Console.WriteLine("The application is not terminating");
}
}
catch(Exception e)
{
Console.WriteLine("Unhandled exception in unhandled exception handler == " +
e.ToString( ));
}
finally
{
// Add other exception logging or cleanup code here.
}
}
Next, you should add code to your application to wire up this event
handler. The code to wire up the event handler should be executed as
close to the start of the application as possible. For example, by
placing this code in the Main method:
public static void Main( )
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(LastChanceHandler);
//...
}
you are assured of being able to clean up after any unhandled
exception.
The exception event handler takes two parameters. The first is the
sender object, which is the AppDomain object that
threw the exception. The second argument is an
UnhandledExceptionEventArgs object. This object
contains all the relevant information on the unhandled exception.
Using this object, we can obtain the actual exception object that was
thrown as well as a Boolean flag that indicates whether the
application will terminate.
Exception event handlers are a
great help when used in multithreaded code. If an unhandled exception
is thrown in a thread other than the main thread, that thread aborts.
However, only the worker thread, and not the application as a whole,
will terminate. But you are not clearly notified when the CLR aborts
this thread, which can cause some interesting debugging problems.
However, when an exception event handler is used, you can be notified
of any unhandled exceptions that occur in any worker thread and that
cause it to abort.
The exception event handler captures unhandled exceptions only for
the primary application domain. Any application domains created from
the primary application domain do not fire this event for unhandled
exceptions.
See Also
See the "Error Raising and Handling
Guidelines" and
"UnhandledExceptionEventHandler
Class" topics in the MSDN documentation.
|