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.
What Should Never Happen... Did
4 days ago
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