In a previous post, I reported that stack overflow exceptions can only be caught by structured exception handlers. We had a little internal discussion following this which I found interesting, I thought you might too.
Naveed explained that on Windows, it is possible to catch hardware exceptions with C++ exception handlers because Microsoft implemented C++ exceptions with SEH.
There are two routes to catching hardware exceptions:
- Using catch(...)
- Registering a structured exception handler to C++ translator function
As a bonus, he wrote a sample which demonstrates both of these techniques. His translator function converts SEH exceptions to unsigned ints, although you could build a custom C++ object and throw that instead.
// SEHInCppTest.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include
#include
void SehToUnsignedIntCppExceptionTranslator(unsigned int e, _EXCEPTION_POINTERS* p)
{
throw (unsigned int)e;
}
int _tmain(int argc, _TCHAR* argv[])
{
try {
__asm cli
} catch( ... ) {
printf("Caught: Privileged instruction.\n" );
}
try {
int* pInt=0;
*pInt = 10;
} catch( ... ) {
printf("Caught: Access violation.\n" );
}
try {
int dividend=1;
int divisor=0;
int quotient = dividend / divisor;
} catch( ... ) {
printf("Caught: Integer division by zero.\n" );
}
// requires compiler flag /EHa to use our translator function
_set_se_translator( SehToUnsignedIntCppExceptionTranslator );
try {
__asm cli
} catch( unsigned int e ) {
printf("Caught: SEH Exception Code (via translation) 0x%X.\n", e );
}
try {
int* pInt=0;
*pInt = 10;
} catch( unsigned int e ) {
printf("Caught: SEH Exception Code (via translation) 0x%X.\n", e );
}
try {
int dividend=1;
int divisor=0;
int quotient = dividend / divisor;
} catch( unsigned int e ) {
printf("Caught: SEH Exception Code (via translation) 0x%X.\n", e );
}
return 0;
}
1 comment:
Hey, wow, that's really neat. Now my applications can handle Runtime Exceptions (not that my code is usually poorly written enough to encounter them often).
I have a lower level question about try-catch blocks.
How are these things handled on the stack? I know it might be compiler-dependent, but... what I am thinking is that try clauses have their own stack frame with a magic value and a pointer(s) to relevant catch clauses. During stack unwinding after an exception is raised, code looks for the magic value to find try clauses, then iterates though the catch clauses for a relevant handler?
That's just a guess...
Please, if you know, email me at normlegaia@gmail.com.
Post a Comment