Friday, August 6, 2010

A lost and found exception

These days, I am working on a defect related to a lost exception due to a catch-all handler as following,

try
{
    do_something();
}
catch (...)
{
    log_message();
}

From the log message, it indicates that some exception has been caught in the catch-all handler. However, I do not have any exception specific information, such as exception code and type. Without any exception specific information, it would be impossible to figure out the cause of the exception.

Then I think whether it is possible to intercept an exception before a handler handles it. On Windows, there is a run-time API to translate a Win32 exception to a C++ typed exception before a C++ exception handler handles it.

_se_translator_function _set_se_translator(_se_translator_function seTransFunction);

typedef void (*_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS *).

Before a Win32 exception is handled by a C++ catch handler, including a catch-all handler, _set_se_translator intercepts the Win32 exception and then process it based on the _se_translator_function provided.

So I change the code as following,

void new_trans_func( unsigned int uCode, EXCEPTION_POINTERS* pExp )
{
    // process the exception based on uCode and pExp
}

try
{
    _se_translator_function old_trans_func = _set_se_translator(new_trans_func);
    do_something();
    _set_se_translator(old_trans_func);
}
catch (...)
{
    log_message();
}

I enable /EHa, recompile the code, and set a breakpoint in new_trans_func. When the breakpoint is hit, I dump the exception code and record.

After knowing what exception has been thrown, I enable the debugger to break on the exception before it is handled by any exception handler.

1 comments:

  1. Good idea! It can be really useful in certain situations. Though in most cases it’s better not to use catch-all statements at all, allowing the process to crash when unexpected exception rises.

    ReplyDelete