Re: Mixing /EHs and /EHa (structured exceptions)
"Igor Tandetnik" <itandetnik@mvps.org> wrote in message
news:eqN%23AtG9HHA.5404@TK2MSFTNGP02.phx.gbl...
"Kenneth Porter" <shiva.blacklist@sewingwitch.com> wrote in message
news:Xns99A7D880214CBshivasewingwitchcom@207.46.248.16
From http://msdn2.microsoft.com/en-us/library/1deeycx5(VS.80).aspx
Use /EHs to specify the synchronous exception handling model (C++
exception handling without structured exception handling exceptions).
If you use /EHs, then your catch clause will not catch asynchronous
exceptions. Also, in Visual C++ 2005, all objects in scope when the
asynchronous exception is generated will not be destroyed even if the
asynchronous exception is handled. Under /EHs, catch(...) will only
catch C++ exceptions. Access violations and System.Exception
exceptions will not be caught.
Use /EHa to specify the asynchronous exception handling model (C++
exception handling with structured exception handling exceptions).
/EHa may result in a less performant image because the compiler will
not optimize a catch block as aggressively, even if the compiler does
not see a throw.
I read that to mean that it changes the code for the catch, not the
throw.
Catching structured exceptions in the catch(...) clause is a side-effect
of /EHa, not the primary goal. The main difference between /EHs and /EHa
is hinted at in the second paragraph. Under /EHs, the compiler assumes
that a C++ exception can only come from a throw statement. So if it can
prove that a particular piece of code doesn't contain such statements,
then it can optimize away exception handling frames around it.
Note that try/catch clause is not the only source of such frames: every
time there is an automatic variable of class type with non-trivial
destructor (either explicitly declared or created as a temporary), the
compiler has to set up exception handling around its scope to run its
destructor if an exception is thrown. These frames can also be optimized
away under /EHs if the compiler believes no exceptions can emanate from a
particular piece of code. Thus, even if you manage to catch such an
exception higher in the stack, your program is in an undetermined state
since some or all destructors of local variables that should have run
haven't.
Under /EHa, the compiler assumes that an exception may arise at any point,
and never removes exception frames.
Nonetheless, it is perfectly appropriate to add an SEH handler to a program
mostly compiled with /EHs. The OP did after all describe it as a "crash
handler". The undetermined state of the program will be no worse than if
the exception was not caught at all, and certainly some useful information
can be dumped such as a stack trace or minidump.
But, as Igor says, without /EHa, you cannot expect to recover from an
asynchronous exception. At best you can try to save the user's data to a
crashdump file for reprocessing and recovery next time your app is run.
Don't under any circumstances overwrite the user's good data files on disk.
You may even want to implement "dirty" flags for parts of your internal data
structure to determine which parts, if any, might be inconsistent.
Also you should use __try/__except, not catch (...), because catch (...)
gives you zero information about the exception or the program state when it
occurred.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925