• No results found

Exception Handling on Windows

On Windows, an exception is an event that occurs during the execution of a program. There are two kinds of exceptions: hardware exceptions and software exceptions. Hardware exceptions are comparable to signals such as SIGSEGV and SIGKILL on Solaris OS and Linux. Software exceptions are initiated explicitly by applications or the operating system using the RaiseException()API.

On Windows, the mechanism for handling both hardware and software exceptions is called structured exception handling (SEH). This is stack frame-based exception handling similar to the C++ and Java exception handling mechanism. In C++ the __try and __except keywords are used to guard a section of code that might result in an exception, as in the following example:

__try {

// guarded body of code } __except (filter-expression) {

// exception-handler block }

The __except block is filtered by a filter expression that uses an exception code (integer code returned by the GetExceptionCode() API), or exception information

(GetExceptionInformation() API), or both.

The filter expression should evaluate to one of the following values:

EXCEPTION_CONTINUE_EXECUTION= -1

The filter expression has repaired the situation, and execution continues where the

exception occurred. Unlike some exception schemes, SEH supports the resumption model as well. This is much like Unix signal handling in the sense that after the signal handler finishes, the execution continues where the program was interrupted. The difference is that the handler in this case is just the filter expression itself and not the __except block.

However, the filter expression might also involve a function call.

EXCEPTION_CONTINUE_SEARCH= 0

The current handler cannot handle this exception. Continue the handler search for the next handler. This is similar to the catch block not matching an exception type in C++ and Java.

EXCEPTION_EXECUTE_HANDLER= 1

The current handler matches and can handle the exception. The __except block is executed.

The __try and __finally keywords are used to construct a termination handler as shown below.

__try {

// guarded body of code } __finally {

6.2 Exception Handling on Windows

// __finally block }

When control leaves the __try block (after exception or without exception), the __finally block is executed. Inside the __finally block, the AbnormalTermination() API can be called to test whether control continued after the exception or not.

Windows programs can also install a top-level unhandled exception filter function to catch exceptions that are not handled in a __try/__except block. This function is installed on a process-wide basis using the SetUnhandledExceptionFilter() API. If there is no handler for an exception, then UnhandledExceptionFilter() is called, and this will call the top-level unhandled exception filter function, if any, to catch that exception. This function also shows a message box to notify the user about the unhandled exception.

Windows exceptions are comparable to Unix synchronous signals that are attributable to the current execution stream. In Windows, asynchronous events such as console events (for example, the user pressing Ctrl-C at the console) are handled by the console control handler registered using the SetConsoleCtlHandler() API.

If an application uses the signal() API on Windows, then the C runtime library (CRT) maps both Windows exceptions and console events to appropriate signals or C runtime errors. For example, CRT maps Ctrl-C to SIGINT and all other console events to SIGBREAK. Similarly, if you register the SIGSEGV handler, the C runtime library translates the corresponding exception to a signal. The CRT library startup code implements a __try/__except block around the main() function. The CRT's exception filter function (named _XcptFilter) maps the Win32

exceptions to signals and dispatches signals to their appropriate handlers. If a signal's handler is set to SIG_DFL (default handling), then _XcptFilter calls UnhandledExceptionFilter.

With Windows XP or Windows 2003, the vectored exception handling mechanism can also be used. Vectored handlers are not frame-based handlers. A program can register zero or more vectored exception handlers using the AddVectoredExceptionHandler API. Vectored handlers are invoked before structured exception handlers, if any, are invoked, regardless of where the exception occurred.

Vectored exception handler returns one of the following values:

EXCEPTION_CONTINUE_EXECUTION: Skip next vectored and SEH handlers.

EXCEPTION_CONTINUE_SEARCH: Continue next vectored or SEH handler.

Refer to the Microsoft web site athttp://www.microsoft.comfor further information on Windows exception handling.

6.2.1 Signal Handling in the HotSpot Virtual Machine

The HotSpot VM installs a top-level exception handler using the

SetUnhandledExceptionFilterAPI (or the AddVectoredExceptionHandler API for 64-bit) during VM initialization.

It also installs win32 SEH using a __try /__except block in C++ around the thread (internal) start function call for each thread created.

Finally, it installs an exception handler around JNI functions.

If an application must handle structured exceptions in JNI code, it can use __try /__except statements in C++. However, if it must use the vectored exception handler in JNI code then the handler must return EXCEPTION_CONTINUE_SEARCH to continue to the VMs exception handler.

In general, there are two categories of situations in which exceptions arise:

Situations where signals are expected and handled. Examples include the implict null handling cited above where accessing a null causes an EXCEPTION_ACCESS_VIOLATION, which is handled.

Unexpected exceptions. An example is EXCEPTION_ACCESS_VIOLATION when executing in VM code or in JNI or native code. In these cases the signal is unexpected, and fatal error handling is invoked to create the error log and terminate the process.

6.2.2 Console Handlers

The HotSpot Virtual Machine registers console events as shown in the following table.

Console Event Signal Usage

CTRL_C_EVENT SIGINT Terminate process. (optional)

CTRL_CLOSE_EVENT CTRL_LOGOFF_EVENT CTRL_SHUTDOWN_EVENT

SIGTERM Used by the shutdown hook mechanism when the VM is terminated abnormally. (optional)

CTRL_BREAK_EVENT SIGBREAK Thread dump support. To dump Java stack traces at the standard error stream. (optional)

If an application must register its own console handler, then the -Xrs option can be used. With this option, shutdown hooks are not run on SIGTERM (with above mapping of events) and thread dump support is not available on SIGBREAK (with above mapping Ctrl-Break event).

6.2 Exception Handling on Windows

Submitting Bug Reports

This chapter provides guidance on how to submit a bug report. It includes suggestions about what to try before submitting a report and what data to collect for the report.