OWL NExt - Knowledge Base

[ Home | Contents | Search | Next | Previous | Up ]

Safe to throw C++ exception out of SEH __catch block?

Date: 11/30/99
Time: 12:55:15 AM

It seems to work, but my question is, it it supposed to? I assume that,
because a __catch block can potentially execute *any* code (meaning, any
other code that might throw a C++ exception -- or another SEH exception for
that matter!), it *better* work.

I ask this question because, if the above is true, there's a natural way to
convert normally unhandled SEH exceptions (such as access violations) into
standard C++ exceptions using the Win32 API function
SetUnhandledExceptionFilter(). Observe...

Here's small program that converts a typical SEH "access violation" into a
standard C++ "runtime_error" exception, which is caught and displayed in
WinMain(). Although I included the SEH details directly here, they could
easily be hidden away in their own file leaving the C++ code "SEH-free"
(apart from the fact that it sometimes handles C++ exceptions that
originated from SEH exceptions).

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#include <stdexcep>

LONG APIENTRY ThrowCppException(PEXCEPTION_POINTERS*)
{
throw std::runtime_error("Oops!");
}

void Crash()
{
*reinterpret_cast<char*>(-1) = 'X';
}

int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
SetUnhandledExceptionFilter(ThrowCppException);

bool done = false;

while (!done)
{
try
{
Crash();
}
catch (std::exception& x)
{
if (MessageBox(0, "Continue?", x.what(), MB_YESNO) == IDNO)
done = true;
}
}

return 0;
}

This program displays a nice custom "Oops!" message box when the Crash()
function causes an access violation (instead of the system's default "your
app has bombed, now you must pay -- mwu-ha-hA-HA" box). I included the
while-loop just to demonstrate that you can even have the program continue
after "crashing". If the declines the option to continue, the program
gracefully terminates normally.

I also tested code similar to the above with local objects in various
locations on the stack. They were all destroyed properly during the stack
unwinding for the *C++* exception throw (what I would have expected).

Regards,
Matt

Last changed: July 14, 2001