From: David Abrahams (abrahams_at_[hidden])
Date: 2000-05-28 08:05:37
----- Original Message -----
From: "Bill Klein" <bill_at_[hidden]>
Sent: Sunday, May 28, 2000 7:48 AM
Subject: Re: [boost] solution: Microsoft JIT debugging and catch(...)
> Hi Dave,
> I'm not sure if this is an explanation for the behaviour
> you're seeing, but I did find out a while ago that if you
> want to get any sort of consistent behaviour with VC++
> with regards to access-violation-type-things throwing
> exceptions, you need to change the (default) /GX release
> mode compiler switch to /EHa.
> Now, if you try to run this program in Debug mode, the
> access violation gets caught in the ... block. Well, ok,
> non-standard, but cool.
No, not cool at all. A crash is a crash, not a C++ exception, and I as the
programmer want to know about it. I want to know the exact state of the
program when the crash occurred and not some "recovered" version of that
state. We do ourselves, and our code, no favors by using a technique which
obscures our mistakes.
Turning a crash into an exception might *almost* be OK for the release
version of a program, as a last-ditch form of recovery, but it is unlikely
to work. Exception-safety depends on knowing which operations can throw, and
nobody expects a pointer-dereference to throw an exception. It's one of
those fundamental operations in the language which doesn't throw
exceptions - indeed, writing exception-safe code in an environment where
*everything* can throw is impossible. So it is more than likely that if a
crash is turned into an exception, some invariant maintained by
exception-recovery code ends up violated. I'm leaving aside entirely the
condition that caused the crash in the first place. The reason I say it
might *almost* be OK as a last-ditch recovery effort is that normally I
would want to take special, extra-cautious recovery-and-shutdown actions in
the case of such a crash, but as it stands there's no way to tell such a
beast from a regular C++ exception.
> Now if you try to run it in release
> mode, you'll see that it *doesn't* get caught!
I have tried both options with my test program, and they exhibit identical
behaviors. I think what the Microsoft documentation says is that unless you
use /EHa, certain destructor cleanups might not run when a structured
exception (crash) causes the stack to unwind. But that's exactly the
behavior I'm trying to avoid here. The point is that with my patch, after a
crash the system will offer to drop you into the debugger, no matter how
many catch(...) blocks you write. You will arrive at the point of the crash,
and no intervening recovery code will have run.
> Not nice to
> have such inconsistent behaviour in debug/release mode. The
> only way to fix it up (AFAIK) is to change the /GX compiler
> switch to /EHa in release mode: now they act the same way.
> Note: You need to use the EHa switch *even* if you are using
> the _set_se_translator trick.
Not if you don't care about unwinding from structured exceptions ;)
But thanks for the info. If I *do* ever decide to take advantage of this
behavior, it's good to know how to do it right.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk