Help: Unwinding the C++ stack...throw, longjmp & threads

craig@jcb-sc.com craig@jcb-sc.com
Wed Aug 25 07:33:00 GMT 1999


>Of course the chance of getting a signal that you want to throw on
>just as malloc() returns, combined with the situation where you
>actually care about the memory leak at this juncture, combined
>with the situation where the last catch that is released isn't
>going to just free a whole epoch of allocations, is an
>extremely low probability circumstance.  I understood the
>example but thought of this case as being lost in the 'noise'.

Not that I've been paying close attention to this thread or anything,
but if you're talking about how a *system* should be designed,
rather than how a specific *application* (say, a game or a kiosk
display or the guidance system for a nuclear missile), there's no
such thing as a window like this being lost in the "noise".

In short, when designing a system like a general-purpose compiler,
operating system, and so on, assume every window of opportunity for
lossage approaches being infinitely wide.  If lossage is still acceptable,
then fine, else the mere opportunity is unacceptable.

(Whereas, for an application, you can refine your analysis to take
into account the risks if the window is hit.  If the game simply
crashes and that's okay, or if the kiosk system can simply and quickly
reboot without losing any important data, fine.  The missile is,
of course, a whole 'nother story.)

For example, the probability of an async exception taking effect between
the end of a critical (protected) region within the malloc() code and
the storing of the pointer into the variable is at least two orders of
magnitude *higher* than most programmers would reckon based on their
simplistic analysis of the instruction stream executed.  (This is due
to higher likelihoods of cache, TLB, and resident-page misses upon returning
from a procedure than while executing typical straightline code.  Add
to that whatever code gets executed to exit the critical region....)

Further, while the *overall* likelihood of a window like this being
hit might be statistically small, in a *given* application that happens
to have an exposure to ill effects from it, especially in a given
*deployment* of that application, the likelihood might near 100% within
a reasonably small timeframe.  (It would not be too strange, to me,
to hear that an application built on a system with bugs like this
failed *only* on one out of thousands of machines on which it's deployed,
the only difference being that that one machine is a 400MHz Pentium III
while all the others are 433MHz, for example.)

I've seen too many projects and products take *huge* hits in perceived
robustness, utility, and wasted developer/debugging time due to supposedly
"vanishingly small" windows like this being pried open, by various
combinations of circumstances, to the point of repeated failure, to
ever again accept "lost in the noise" as an excuse for designing in such
windows.

Further, few people who say things like "lost in the noise" understand
the fine distinctions between *types* of noise.  In this case, I hope
you don't consider synchronous bugs (bugs triggered by normal,
straightline code) as in any way similar to asynchronous bugs.
Excellent programmers can do a great job squashing the former
kind -- very few understand how to even begin setting up a test
bed that finds the latter (I could only *begin* to guess at that,
myself, offhand).

My impression is that at least some people in this discussion already
understand these issues, perhaps all of them.

My guess is that if, indeed, the problem mentioned is "lost in the noise",
then the overall mechanism must be thoroughly explained as not able to
cope with those sorts of coding constructs (to wit, pretty much any
means a programmer might typically use to test how far some chunk of
imperative code progressed before hitting a signal).

That shouldn't be surprising or worrisome, given that C, C++, Fortran,
etc. were not designed from the ground up as "transaction-based"
languages...but I think too many programmers are under the impression
they work that way by magic.  The transition the vast majority of
today's programmers have gone through, of single-user/single-task PC
over to multi-user/multi-task/multi-node/dynamically-partitioning
Internet (e.g. client/server programming), seems to have left a lot
of them doing the latter sort of programming without even realizing
they don't know how.  (In that sense, I was "lucky", having cut my
teeth on timesharing systems before there were PC's, and having come
so "late to the [PC] game" that they were already beginning to discover
multi-tasking, so I had little opportunity to gain ground by "forgetting"
all the OS-design worries I'd picked up over the years.)

That being said, my experience *before* the PC industry suggested that
most programmers (even *good* ones) didn't know how to architect, design,
or implement robust systems involving inherently asynchronous activities,
and yet were unaware of the issues and therefore thought they could.
It's painful work getting this stuff right -- I remember spending *hours*
just verifying that a particular shared-resource management scheme,
implementing very simple primitives, was bullet-proof.  Not fun, but
necessary, especially since I didn't want to have to debug the async
aspects of the code I was writing.  In that case, I'd already had to
completely overhaul the *architecture* and *design* of the system,
after more experienced programmers hadn't even thought about what it
would take to make it bullet-proof at those levels.

        tq vm, (burley)

P.S. In case anyone's thinking "gee, Craig, if you think about it,
you're essentially saying most programmers, and therefore most programs,
don't really work in the presence of exceptions, especially asynchronous
ones", all I can say is, yes, I've already thought about that, and,
indeed, tentatively come to that conclusion.  But I've done very little
reading up on today's concepts of exceptions, asynchronous or otherwise --
last I really paid attention to these issues, I was reasonably solid
on the relevant Multics-like concepts.  Perhaps today's designers have
worked out the kinks, but my general impression is that the architects
of Multics took things much more seriously than do today's (for both
good and ill).  And the programmers who tried to properly use the
underlying, *robust* technologies like signals often failed, despite
there being very few of them, and despite their being permitted to do
such programming only after having spent a few years in a cave with
a guru, so I alternate between hoping today's whiz-kid programmers "just
get" this stuff and fearing they're basically completely clueless
about it, as they design and build the Global Infrastructure Of The
New Millenium.  ;-)


More information about the Gcc mailing list