Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

exceptions

1 view
Skip to first unread message

Michael D. Berger & Rosalie A. Clavez

unread,
Feb 5, 2003, 9:09:50 PM2/5/03
to
Are exceptions thread-safe? More precisely I mean if:

1. Thread A throws an exception that is to be caught in Thread A.

2. At the worst possible time, what ever that might be, Thread B
throws an exception that is to be caught in Thread B.

Will I get the expected results?
In Linux?
In Solaris?
In MS Visual C++?
In ACE on each of these systems?

Thanks for your help.
Mike.

--
Michael D. Berger
m.d.b...@ieee.org

Ian

unread,
Feb 5, 2003, 11:35:52 PM2/5/03
to
Michael D. Berger & Rosalie A. Clavez wrote:
> Are exceptions thread-safe? More precisely I mean if:
>
> 1. Thread A throws an exception that is to be caught in Thread A.
>
> 2. At the worst possible time, what ever that might be, Thread B
> throws an exception that is to be caught in Thread B.
>
> Will I get the expected results?
> In Linux?
> In Solaris?
> In MS Visual C++?
> In ACE on each of these systems?
>

Not what I'd call thread safe, but yes, exceptions are per thread (after
all, threads don't share stacks, do they?).

ian

Attila Feher

unread,
Feb 6, 2003, 12:19:54 AM2/6/03
to
Ian wrote:
> Michael D. Berger & Rosalie A. Clavez wrote:
>> Are exceptions thread-safe?

Nope.

>> More precisely I mean if:
>>
>> 1. Thread A throws an exception that is to be caught in Thread A.
>>
>> 2. At the worst possible time, what ever that might be, Thread B
>> throws an exception that is to be caught in Thread B.

As logn as you do not try to cross thead boundaires it is A OK. To ensure
that place a catch all into the threads main function - and put an error
message or generic handling (such as reporting error to somewhere,
cancelling the last ttransaction) etc.

Attila


Alexander Terekhov

unread,
Feb 6, 2003, 5:54:49 AM2/6/03
to

Attila Feher wrote:
>
> Ian wrote:
> > Michael D. Berger & Rosalie A. Clavez wrote:
> >> Are exceptions thread-safe?
>
> Nope.

What do you mean?

> >> More precisely I mean if:
> >>
> >> 1. Thread A throws an exception that is to be caught in Thread A.
> >>
> >> 2. At the worst possible time, what ever that might be, Thread B
> >> throws an exception that is to be caught in Thread B.
>
> As logn as you do not try to cross thead boundaires it is A OK.

How can you cross thread boundaries with respect to throw/catch
thing [unexpected() and terminate() for uncaught exception aside
for a moment]?

regards,
alexander.

Michael D. Berger & Rosalie A. Clavez

unread,
Feb 6, 2003, 7:56:53 AM2/6/03
to

What would be a better meaning of thread safe?

Michael D. Berger & Rosalie A. Clavez

unread,
Feb 6, 2003, 7:59:31 AM2/6/03
to

Do I need unextected() treatment in each thread to pervent termination?

Joseph Seigh

unread,
Feb 6, 2003, 8:42:54 AM2/6/03
to

"Michael D. Berger & Rosalie A. Clavez" wrote:
>

> Are exceptions thread-safe? More precisely I mean if:
>
> 1. Thread A throws an exception that is to be caught in Thread A.
>
> 2. At the worst possible time, what ever that might be, Thread B
> throws an exception that is to be caught in Thread B.
>
> Will I get the expected results?
> In Linux?
> In Solaris?
> In MS Visual C++?
> In ACE on each of these systems?
>

In theory they could be. In practice not thread-safe unless proven otherwise.
The main reason for this is that C++ (or their adherents anyway) claims to be
thread neutral. That is nonsense. As far as threaded programming is concerned,
if you are not part of the solution, you are part of the problem. The C++
attitude is really outright antipathy. Can you really trust anything produced
in that kind of environment to be truly thread-safe?

What this means is that you have to look at each class and determine whether
its exception generation and handling is thread-safe. I'd say stuff is
mostly thread-safe if you understand C++ threaded programming conventions.
At least there aren't a great deal of obvious problems. I wouldn't worry
too much. It's not like C++ is used for safety critical systems or anything
like that.

Joe Seigh
C++

Alexander Terekhov

unread,
Feb 6, 2003, 9:11:39 AM2/6/03
to

"Michael D. Berger & Rosalie A. Clavez" wrote:
[...]

> Do I need unextected() treatment in each thread to pervent termination?

Short answer: don't mess with unexpected() [and terminate()] handlers.
Std::bad_exception-"transformations" aside, let we default one do The
Right Thing -- terminate()->abort().

regards,
alexander.

Attila Feher

unread,
Feb 6, 2003, 9:15:01 AM2/6/03
to
Michael D. Berger & Rosalie A. Clavez wrote:

> Do I need unextected() treatment in each thread to pervent
> termination?

catch all, as I wrote in another thread. catch all in the "main" function
fo your thread.

A


Alexander Terekhov

unread,
Feb 6, 2003, 9:26:33 AM2/6/03
to

Blind "catch all" makes no sense at all.

regards,
alexander.

Attila Feher

unread,
Feb 6, 2003, 9:32:37 AM2/6/03
to
Alexander Terekhov wrote:
>> catch all, as I wrote in another thread. catch all in the "main"
>> function fo your thread.
>
> Blind "catch all" makes no sense at all.

If you think that a crash make more sense - do that


Alexander Terekhov

unread,
Feb 6, 2003, 9:41:18 AM2/6/03
to

Michael D. Berger & Rosalie A. Clavez

unread,
Feb 6, 2003, 9:17:14 PM2/6/03
to

These threads are permanent, with while(true){stuff}. Letting
them terminate is not an option. A throw means we failed this time,
but next time might be better. As far as I can see, I must use
catch(...) within the loop of each thread. True? Does this rule
out all possibilities of unexpected exceptions? Is there anything
that mutexes or condition variables or sockets can do that can
escape this procedure? Is the underlying thread implementation
reentrant so that all variables are on the stacks? I hope so,
and this was implied by a previous note in this thread.
Thanks,

Hillel Y. Sims

unread,
Feb 6, 2003, 11:50:24 PM2/6/03
to

"Michael D. Berger & Rosalie A. Clavez" <mdbe...@radix.net>
wrote in message news:3E43172A...@radix.net...

>
> These threads are permanent, with while(true){stuff}. Letting
> them terminate is not an option. A throw means we failed this
time,
> but next time might be better.

while (true) {
try {
stuff
}
catch (std::exception& e) {
// swallow and maybe try again (or maybe break out of the
loop) --
// exception-safe code is cleaned up, transactions are
rolled-back
// memory freed, program state remains consistent, etc.
}
}

As far as I can see, I must use
> catch(...) within the loop of each thread. True? Does this
rule
> out all possibilities of unexpected exceptions? Is there
anything
> that mutexes or condition variables or sockets can do that can
> escape this procedure?

Stay away from catch(...), it can catch stuff like thread
cancellation exceptions or access violations which you don't
really want to catch. Use std::exception as your common base
class for 'well-known' C++ exceptions.

hys

--
(c) 2003 Hillel Y. Sims
hsims AT factset.com


Attila Feher

unread,
Feb 7, 2003, 12:18:58 AM2/7/03
to

> Stay away from catch(...), it can catch stuff like thread
> cancellation exceptions

There is no such standard exception.

> or access violations which you don't
> really want to catch.

Access violations generate signals and not exceptions.

Anyways if you have any propriatery exceptions you need to handle, those you
catch before the catch(...). But then the _only_ safe thing to do is catch
all.

> Use std::exception as your common base
> class for 'well-known' C++ exceptions.

And ray that no other exception will come, because then you crash!

A


Peter Koch Larsen

unread,
Feb 7, 2003, 7:13:28 AM2/7/03
to

"Michael D. Berger & Rosalie A. Clavez" <mdbe...@radix.net> skrev i en
meddelelse news:3E41C3EE...@radix.net...

> Are exceptions thread-safe? More precisely I mean if:
>
> 1. Thread A throws an exception that is to be caught in Thread A.
>
> 2. At the worst possible time, what ever that might be, Thread B
> throws an exception that is to be caught in Thread B.
--
> Michael D. Berger


Since threads are not yet part of the C++ standard, that guarantee cannot be
given. It all depends on your implementation, and I guess most C++ compilers
should get it right, but for now, You must check to see if the behaviour is
all right.

Kind regards
Peter


Arnold Hendriks

unread,
Feb 7, 2003, 7:11:38 AM2/7/03
to
Attila Feher <attila...@lmf.ericsson.se> wrote:
>> Stay away from catch(...), it can catch stuff like thread
>> cancellation exceptions
> There is no such standard exception.
Some platforms don't care about that.

>> or access violations which you don't
>> really want to catch.
> Access violations generate signals and not exceptions.

Some platforms disagree. Unfortunately. With Microsoft C++, and similair
compilers such as Borland C++, being one of the biggest offenders.

--
Arnold Hendriks <a.hen...@b-lex.com>
B-Lex Information Technologies, http://www.b-lex.com/

Attila Feher

unread,
Feb 7, 2003, 7:23:02 AM2/7/03
to
Arnold Hendriks wrote:
> Attila Feher <attila...@lmf.ericsson.se> wrote:
>>> Stay away from catch(...), it can catch stuff like thread
>>> cancellation exceptions
>> There is no such standard exception.
> Some platforms don't care about that.

Some one company called MicroSoft you mean? Well - no wonder.

>>> or access violations which you don't
>>> really want to catch.
>> Access violations generate signals and not exceptions.
> Some platforms disagree. Unfortunately. With Microsoft C++, and
> similair compilers such as Borland C++, being one of the biggest
> offenders.

Except for one thing: we were taling about C++ exceptions, and not Windows
structured exceptions. And the two has nothing to do with each other.

A


Alexander Terekhov

unread,
Feb 7, 2003, 7:42:20 AM2/7/03
to

Attila Feher wrote:
>
> Arnold Hendriks wrote:
> > Attila Feher <attila...@lmf.ericsson.se> wrote:
> >>> Stay away from catch(...), it can catch stuff like thread
> >>> cancellation exceptions
> >> There is no such standard exception.
> > Some platforms don't care about that.
>
> Some one company called MicroSoft you mean? Well - no wonder.

http://groups.google.com/groups?selm=c29b5e33.0202161451.2ef75f1f%40posting.google.com

>
> >>> or access violations which you don't
> >>> really want to catch.
> >> Access violations generate signals and not exceptions.
> > Some platforms disagree. Unfortunately. With Microsoft C++, and
> > similair compilers such as Borland C++, being one of the biggest
> > offenders.
>
> Except for one thing: we were taling about C++ exceptions, and not Windows
> structured exceptions. And the two has nothing to do with each other.

Except for one thing: catch(...) catches everything.

regards,
alexander.

Attila Feher

unread,
Feb 7, 2003, 7:52:12 AM2/7/03
to
Alexander Terekhov wrote:
>> Some one company called MicroSoft you mean? Well - no wonder.
>
>
http://groups.google.com/groups?selm=c29b5e33.0202161451.2ef75f1f%40posting.
google.com

>> Except for one thing: we were taling about C++ exceptions, and not


>> Windows structured exceptions. And the two has nothing to do with
>> each other.
>
> Except for one thing: catch(...) catches everything.

Except for one thing: catch(...) does not catch everything. For example it
does not catch cold _or_ structured Windows exceptions. At least not on a
conforming compiler.

A


Attila Feher

unread,
Feb 7, 2003, 7:55:22 AM2/7/03
to
Alexander Terekhov wrote:
>
http://groups.google.com/groups?selm=c29b5e33.0202161451.2ef75f1f%40posting.
google.com

Well, so? I see a link in your link onto a page which show some C code with
macros for exception handling. What does this have to do with C++
exceptions? Or did I miss something? I thought the original question was
about C++ exceptions.


Alexander Terekhov

unread,
Feb 7, 2003, 8:09:25 AM2/7/03
to

Attila Feher wrote:
>
> Alexander Terekhov wrote:
> >
> http://groups.google.com/groups?selm=c29b5e33.0202161451.2ef75f1f%40posting.
> google.com
>
> Well, so? I see a link in your link onto a page which show some C code with
> macros for exception handling. What does this have to do with C++
> exceptions?

http://groups.google.com/groups?selm=3D711160.2DE3FC09%40web.de
(Hi There! Greetings from the ``yellow zone.'')

regards,
alexander.

Alexander Terekhov

unread,
Feb 7, 2003, 8:28:11 AM2/7/03
to

Attila, your "conforming compiler" is totally busted, then.

regards,
alexander.

Alexander Terekhov

unread,
Feb 7, 2003, 12:40:00 PM2/7/03
to
Attila, I accept your implicit [silent] concession of defeat
(that makes me feel good). ;-)

regards,
alexander.

White Wolf

unread,
Feb 7, 2003, 1:57:46 PM2/7/03
to
"Alexander Terekhov" wrote:
> Attila, I accept your implicit [silent] concession of defeat
> (that makes me feel good). ;-)

All my sorrows are yours if this is what you need to make you feel good.
But I am patiently waiting for your arguments. Not cryptic posts ands
links to them: simple posting as humans do. I am a reasonable man. As
long as noone is playing tones on my nerves. After that I stay
reasonable - only the observer might think I am not, because my reasons
change. :-) Anyways the fact that when I have a high fever nad I can
bearly breath I do not pay attention to cryptic messages and picking
does not mean you have convinced me of anything. I sugegst you try
again, in this time the way you would do it when you wanted the other to
get your message.

WW aka Attila


Hillel Y. Sims

unread,
Feb 8, 2003, 1:58:09 AM2/8/03
to
"Attila Feher" <attila...@lmf.ericsson.se> wrote in message
news:b209i9$peo$1...@newstoo.ericsson.se...

> Alexander Terekhov wrote:
> >
> > Except for one thing: catch(...) catches everything.
>
> Except for one thing: catch(...) does not catch everything.
For example it
> does not catch cold _or_ structured Windows exceptions. At
least not on a
> conforming compiler.
>

*ahem* chapter and verse, please?

Hillel Y. Sims

unread,
Feb 8, 2003, 1:58:08 AM2/8/03
to
"Attila Feher" <attila...@lmf.ericsson.se> wrote in message
news:b1vf0e$kp4$1...@newstoo.ericsson.se...

>
> > Stay away from catch(...), it can catch stuff like thread
> > cancellation exceptions
>
> There is no such standard exception.

This is not comp.std.c++... I can talk about any kind of
exception I want. :-)

>
> > or access violations which you don't
> > really want to catch.
>
> Access violations generate signals and not exceptions.

All the world's not Unix. Welcome to VMS / Windows.

>
> Anyways if you have any propriatery exceptions you need to
handle, those you
> catch before the catch(...). But then the _only_ safe thing
to do is catch
> all.

If you already caught everything you were supposed to, then why
do you want to bother with catch(...) anyhow?

>
> > Use std::exception as your common base
> > class for 'well-known' C++ exceptions.
>
> And ray that no other exception will come, because then you
crash!

That's kind of the point..

White Wolf

unread,
Feb 8, 2003, 3:31:36 AM2/8/03
to
"Hillel Y. Sims" wrote:
> > > Except for one thing: catch(...) catches everything.
> >
> > Except for one thing: catch(...) does not catch everything.
> For example it
> > does not catch cold _or_ structured Windows exceptions. At
> least not on a
> > conforming compiler.
>
> *ahem* chapter and verse, please?

You are kidding yes? The MicroSoft propiatery C-style structured
exceptions are not part of the standard, so if I am right, there is no
way to quote the standard. But I am patiently waiting for your chanpter
and verse telling that non-C++ exceptions should and can be caught by a
C++ try clause in a standard conforming implementation.

WW


White Wolf

unread,
Feb 8, 2003, 3:40:19 AM2/8/03
to
"Hillel Y. Sims" wrote:
> >
> > > Stay away from catch(...), it can catch stuff like thread
> > > cancellation exceptions
> >
> > There is no such standard exception.
>
> This is not comp.std.c++... I can talk about any kind of
> exception I want. :-)

As long as they are valid C++ exceptions, thrown by the C++ throw
keyword - yes.

> > > or access violations which you don't
> > > really want to catch.
> >
> > Access violations generate signals and not exceptions.
>
> All the world's not Unix. Welcome to VMS / Windows.

All the world is not Windows. Welcome to UNIX. You have stated
something to be generally true, which isn't. I am happy you have
realized that. It would be nice though if you would relaize your errors
when you do them, not only when someone else deliberately does it.

BTW I did tell that any exception requires handling in your environment
has to be handled before the catch(...), but for the sake of quarrel
both you and Alexander seem to ignore that comment.

> > Anyways if you have any propriatery exceptions you need to
> handle, those you
> > catch before the catch(...). But then the _only_ safe thing
> to do is catch
> > all.
>
> If you already caught everything you were supposed to, then why
> do you want to bother with catch(...) anyhow?

Caught everything the _environment_ might throw. Everything, which
cannot or better be not be ignored it thrown by the _environment_.
Kapis? Anyways most of those can be ignored as well - as long as it is
done with a sense and with a paranoid enough code.

> > > Use std::exception as your common base
> > > class for 'well-known' C++ exceptions.
> >
> > And ray that no other exception will come, because then you
> crash!
>
> That's kind of the point..

OK. So have a nice drive at 2am to your server rooms to figure out why
does your server keep reastarting in every second. Just because you
could have ignored an exception (ignore here means: not let it crash you
and eg: drop the last transaction what have caused it) but you have
decided to not place that ctach(...) there. So one 12 years old who has
figured out what packet to send to you keeps you server down - without
even flooding... Good luck!

WW


Arnold Hendriks

unread,
Feb 8, 2003, 8:02:43 AM2/8/03
to
White Wolf <wo...@freemail.hu> wrote:
>> > does not catch cold _or_ structured Windows exceptions. At
>> least not on a
>> > conforming compiler.
>>
>> *ahem* chapter and verse, please?

> You are kidding yes? The MicroSoft propiatery C-style structured
> exceptions are not part of the standard, so if I am right, there is no
> way to quote the standard. But I am patiently waiting for your chanpter
> and verse telling that non-C++ exceptions should and can be caught by a
> C++ try clause in a standard conforming implementation.

This is not comp.lang.c++ - the OP was asking about his existing system,
and on some existing systems (and especially with Visual C++, about which
the OP explicitly asked), you /have/ to deal with catch(...) interfering
with correct program behaviour when SEs or whatevers are thrown.

It's fine that catch(...) does not catch non-C++ exceptions on a conforming
compiler, but in real life, most people on Windows aren't working with a
conforming compiler, and have to deal with catch(...) being broken. Ignoring
the problem by hiding behind the C++ standard often does not help, because
switching compilers is often impossible or too expensive.

Alexander Terekhov

unread,
Feb 8, 2003, 11:20:12 AM2/8/03
to

White Wolf wrote:
[...]

> But I am patiently waiting for your chanpter and verse telling that
> non-C++ exceptions should and can be caught by a C++ try clause in
> a standard conforming implementation.

http://lists.boost.org/MailArchives/boost/msg36232.php

< copy&paste >

Subject: exception handling -- forced unwinding


Hi Christophe,

Thanks for the reply and the link to the article.

> In other words, catch(...) will *not* see it.

Ha! But that's still ``doesn't-work-at-all!'' ;-) Seriously,
I really can't make any sense of the idea of *forced* unwinding,
in general. To begin with, it would break rather important [you
even mention it in your article, AFAICS] throw() exception specs,
throw(something) aside for a moment.

It would also break legal code like this:

/* allocate resources -- >>no RAII<< */

try {
/* can't tolerate forced unwinding initiated inside try here */
}
catch(...) {
/* nothrow code here */
}

/* free resources */

and other "variations" that all depend on just-can't-miss-"..."-block-and/
or-the-code-below-it informal semantics of that nice try{/**/}catch(...){/**/}
thing.

As for the thread cancel/exit... that ought to be normal C++ exceptions;
just like any other SEH/C-exception beast, I believe [but there should be
a way to control "hardware"/synchronous-signals stuff ala exc_raise_signal
_exception()[1]; here I somewhat disagree with a few bits in your article,
BTW].

Foreign exceptions [e.g. Java ones while flying (if allowed-via-ex.specs
and/or *expected*-via-catch-handlers ;-) ) over C++ land] should probably
be represented in C++ code as sort of "handles" -- one single C++ exception
type encapsulating all possible foreign exceptions coming from that particular
land/"runtime". Alternatively, perhaps as sort of extension, I'd probably
want to have "a mapping mechanism" that would support native representations
for all exceptions in each and every "runtime" [but that might be rather
problematic, so to speak, I think ;-) ].

setjmp/longjmp is already way too restricted [and that's good], so that it's
practically unusable in C++ code... from "modular programming" point of view,
at least.

IOW, I don't see *any need* for forced unwinding [DEC->Compaq->HP's
exc_capture_context()/exc_longjmp()[2] including ;-) ].

What am I missing here?

regards,
alexander.

[1] http://tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51A_HTML/ARH9MBTE/VNTPRCSS.HTM#exc-sig-hand-coexistence
[2] http://tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51A_HTML/MAN/MAN3/0022____.HTM


----- [Original Message, forwarded, quoted] -----
From: "Alexander Terekhov" <tere...@web.de>
Subject: Fwd:
Sent: Friday, July 19, 2002 9:57 PM


> "DE-DINECHIN,CHRISTOPHE <snip> schrieb am 19.07.02 19:49:24:
> > I've been part of the design of the exception handling for Itanium. I wrote
> > an article on the subject, which you can find here:
> > <http://www.computer.org/concurrency/pd2000/p4072abs.htm>. It should clear a
> > few things up on why we do things that way on Itanium.
> >
> > Contrary to your assumption, the "exception" mentionned in the document is
> > an exception only from the runtime point of view, not from the C++ point of
> > view. In other words, catch(...) will *not* see it. If a compiler generates
> > code where a longjmp causes you to execute code in a catch(...), that
> > compiler has a serious bug :-)
> >
> > > Well, one problem {among couple of others} is that C++ language has
> > > 'a catch thing' with three dots in it:
> > >
> > > try{/**/}/**/catch(...){/**/}
> >
> > My understanding is that the "user-defined code" that the original document
> > refers to is not normally intended to cover such catch-all clauses. Rather,
> > it is intended to let the compiler not have to duplicate code unnecessarily
> > just to avoid some user code. I'll try to illustrate this below.
> >
> > Basically, the Itanium EH model is intended to avoid paying an "exception
> > tax" on the non-exceptional path, even if it means doing more complicated
> > things in case of exceptions. Empirically, on PA-RISC, we observed around
> > 10% performance loss because of EH in some cases, simply because there were
> > optimizations on the regular path that the compiler didn't dare doing
> > anymore. For instance, moving code past a function call. Consider this:
> >
> > try
> > {
> > int a = 0;
> > foo();
> > a = 1;
> > // More code
> > } catch(...)
> > {
> > cout << "a=" << a;
> > }
> >
> > In that case, the foo() function has no way to see the value of a (no
> > address taken). So we can just remove the code that sets a=0 on the
> > non-exceptional path. But then, if an exception is taken, we need to patch
> > up. For instance, the code is rewritten as something like (I'm simplifying,
> > a lot):
> >
> > foo();
> > a = 1;
> > // More code
> > goto after_the_catch;
> >
> > catch_cleanup_code:
> > a = 0;
> > switch(exception_type)
> > {
> > case UNWINDING_FOR_LONGJMP_OR_PTHREAD_CANCEL:
> > ResumeUnwind();
> > default:
> > cout << "a=" << a;
> > }
> >
> > So the "user code" that the text refers about would be the "a=0", not the
> > catch(...) code. Now, why do we need to reinsert that code "a=0" along the
> > path for something like longjmp(), you may ask. The main motive is to avoid
> > duplication of code. The same restoration code also needs to restore
> > registers that the caller will use (for instance, the register where the
> > caller saved the return pointer, otherwise the longjmp() caller would not be
> > able to return itself). We wanted to avoid forcing the compiler to duplicate
> > that path, once for the "setjmp/pthread" unwinding and once for the normal
> > EH case. Note that a lot of this "code" is real code, a lot is unwinding of
> > registers done by the runtime by manipulating the EH stack directly.
> >
> >
> > I hope this clarified things...
> > Christophe
> >
> > "Alexander Terekhov" <tere...@web.de <mailto:tere...@web.de>> wrote in
> > message
> > <news:3D205A8A...@web.de>...
> > > Explanation [relevance w.r.t. C++ exceptions 'model']:
> > >
> > > A) longjmp and C++ exceptions:
> > >
> > > The standard says: "The function signature longjmp(jmp_buf jbuf, int
> > val)
> > > has more restricted behavior in this International Standard. If any
> > automatic
> > > objects would be destroyed by a thrown exception transferring control
> > to
> > > another (destination) point in the program, then a call to
> > ongjmp( jbuf, val)
> > > at the throw point that transfers control to the same (destination)
> > point has
> > > undefined behavior.
> > >
> > > Now, of course, any implementation MAY define whatever behavior it
> > wants for
> > > everything left undefined in the standard [portability aside]...
> > however,
> > > unwinding via-an-exception-that-simply-can't-be-finally-caught ["no
> > language
> > > is allowed to 'catch'"] doesn't really work in C++, AFAICS; please
> > see the
> > > next (B)-item below;
> > >
> > > B) "it does not need to know anything specific about unwinding
> > > done on behalf of longjmp or pthreads cancellation":
> > >
> > > Well, one problem {among couple of others} is that C++ language has
> > > 'a catch thing' with three dots in it:
> > >
> > > try{/**/}/**/catch(...){/**/}
> > >
> > > Now, "User-defined code in a catch clause may still be executed,
> > > but the catch clause must resume unwinding with a call to
> > > _Unwind_Resume when finished. " is basically nothing but
> > > 'auto_rethrow_exception' and 'catch(...)' illustrated here
> > > [transformations of 'legal-throws' into 'now-suddenly-colliding-
> > > throws' plus Ex.Specs 'fencing' aside, for a moment]:
> > >
> > > <http://lists.boost.org/MailArchives/boost/msg23046.php>
> > >
> > > It simply doesn't work, unless I'm just missing something...
> > > then I apologize in advance for the noise.
> > >
> > > > > Also, I'm still awaiting some answer to a couple of 'questions'
> > > > > [misconceptions (AFAICT/IMNSHO)] hinted, for example, here:
> > > > >
> > > > > <http://groups.google.com/groups?selm=3CF802FB.98E837E9%40web.de>
> > > >
> > > > I looked there. I don't see any questions to answer, other than "or am I
> > > > wrong, folks?" at the end.
> > >
> > > Well, another question was [w/o corresponding question mark, though ;-) ]:
> > >
> >

regards,
alexander.

Alexander Terekhov

unread,
Feb 8, 2003, 11:23:04 AM2/8/03
to

White Wolf wrote:
[...]

> > > And ray that no other exception will come, because then you crash!
> >
> > That's kind of the point..
>
> OK. So have a nice drive at 2am to your server rooms to figure out why
> does your server keep reastarting in every second. Just because you
> could have ignored an exception (ignore here means: not let it crash you
> and eg: drop the last transaction what have caused it) but you have
> decided to not place that ctach(...) there. So one 12 years old who has
> figured out what packet to send to you keeps you server down - without
> even flooding... Good luck!

http://groups.google.com/groups?selm=c29b5e33.0202161915.3cd77b6f%40posting.google.com
(Subject: Re: Guru of the Week #82: Solution)

regards,
alexander.

--
http://www.ibmlink.ibm.com/usalets&parms=H_203-002

Alexander Terekhov

unread,
Feb 8, 2003, 12:07:45 PM2/8/03
to

White Wolf wrote:
[...]

> I sugegst you try again, in this time the way you would do it when you
> wanted the other to get your message.

Okay. One more try. No link this time. Copy&paste, instead. And, BTW,
the "totally busted" {C++}ABI specification can be found here:

ftp://download.intel.com/design/Itanium/Downloads/24537003.pdf

Subject: Re: Some issues with Technical Report on C++ Performance (DRAFT)
Newsgroups: comp.std.c++

David Abrahams wrote:
[...]
> First, I think you should make it clear that you're discussing a particular
> ABI specification and not just the C++ standard.

Both; C++ standard stuff: a) implementation-defined propagation to
'nowhere' of uncaught exceptions and b) *required* propagation of
*unexpected* [ex.specs.-wise] exceptions way up to the [sort of]
catch(...) handler of [sort-of] function-try-block *implicitly*
added to each and every function with ex.specs... unless compiler
can prove somehow [a rather interesting job given the existence
(>>in real life<<; NOT in the current version of the C++ standard)
of things like "pthread_stackovf_e -- attempted stack overflow was
detected"] that no exception could ever be trapped by that implicit
catch(...)-in-the-function-try-block, AFAICS.

> This ABI corresponds to a
> set of particular C++ implementations. I'm not sure whether you're drawing
> the right conclusions about "No language is allowed to 'catch'" here, but I
> haven't read the ABI spec. Is it possible that catch clauses are prohibited
> from stopping the unwinding process, but that unwinding will stop, e.g.,
> when it reaches setjmp?

Yes, I think so. Basically, the idea [a rather foolish idea, in my
opinion] is to have "nonlocal GOTO in a multilanguage environment"
that would cause FORCED unwinding [way up to the destination point]
that no one is supposed/allowed to 'intercept'. Well, that's how
thread cancelation works in POSIX... but that's pure C... even w/o
exceptions macros! ;-) I think that in C++, one could either declare
that cancel shall always be re-thrown ['undefined behavior' otherwise],
or, probably even better, allow the 'finalization' of cancel exceptions
in the 'user code' with {implicit, maybe} re-activation of thread
cancelability [it should be disabled while the cancel process/unwinding
running].

[...]
> I don't know what you mean by that. Are you saying that a
> non-type-preserving rethrow from a catch clause is outlawed by this ABI
> specification if a pthreads cancellation or a longjmp passes through it?

Uhmm. AFAICT, catch(...) [during forced unwinding] can't throw anything
other than 're-throw' ["throw;"]. According to my understanding of this
ABI, in the presence of its 'pthreads' cancellation or a 'longjmps', all
catch(...) handlers degenerate suddenly to sort-of function-try-block-
catch(...) handlers, but that a) can't translate anything since neither
cancelation nor 'jumps' can be caught, and b) can't throw anything else
[other than "throw;"] since that would result in *multiple* exceptions
all flying together... I don't think that folks really wanted to have
something like that. Here's the quotes:

"....
A runtime is not allowed to catch an exception if the _UA_FORCE_UNWIND
flag was passed to the personality routine.

Example: Foreign Exceptions in C++. In C++, foreign exceptions can be
caught by a catch(...) statement. They can also be caught as if they
were of a __foreign_exception class, defined in <exception>. The
__foreign_exception may have subclasses, such as __java_exception and
__ada_exception, if the runtime is capable of identifying some of the
foreign languages.

The behavior is undefined in the following cases:

A __foreign_exception catch argument is accessed in any way
(including taking its address).

A __foreign_exception is active at the same time as another
exception (either there is a nested exception while catching
the foreign exception, or the foreign exception was itself
nested).

uncaught_exception(), set_terminate(), set_unexpected(),
terminate(), or unexpected() is called at a time a foreign
exception exists (for example, calling set_terminate() during
unwinding of a foreign exception).

All these cases might involve accessing C++ specific content
of the thrown exception, for instance to chain active exceptions.

Otherwise, a catch block catching a foreign exception is allowed:

to resume normal execution, thereby stopping propagation of
the foreign exception and deleting it, or

to rethrow the foreign exception. In that case, the original
exception object must be unaltered by the C++ runtime.

A catch-all block may be executed during forced unwinding. For
instance, a longjmp may execute code in a catch(...) during stack
unwinding. However, if this happens, unwinding will proceed at
the end of the catch-all block, whether or not there is an explicit
rethrow.

...."

"....
_Unwind_ForcedUnwind

typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
(int version,
_Unwind_Action actions,
uint64 exceptionClass,
struct _Unwind_Exception *exceptionObject,
struct _Unwind_Context *context,
void *stop_parameter );

_Unwind_Reason_Code _Unwind_ForcedUnwind
( struct _Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop,
void *stop_parameter );

Raise an exception for forced unwinding, passing along the
given exception object, which should have its exception_class
and exception_cleanup fields set. The exception object has been
allocated by the language-specific runtime, and has a language-
specific format, except that it must contain an _Unwind_Exception
struct (see Exception Header above).

Forced unwinding is a single-phase process (phase 2 of the normal
exception-handling process). The stop and stop_parameter parameters
control the termination of the unwind process, instead of the usual
personality routine query. The stop function parameter is called for
each unwind frame, with the parameters described for the usual
personality routine below, plus an additional stop_parameter.

When the stop function identifies the destination frame, it transfers
control (according to its own, unspecified, conventions) to the user
code as appropriate without returning, normally after calling
_Unwind_DeleteException. If not, it should return an
_Unwind_Reason_Code value as follows:

_URC_NO_REASON: This is not the destination frame. The unwind
runtime will call the frame's personality routine with the
_UA_FORCE_UNWIND and _UA_CLEANUP_PHASE flags set in actions,
and then unwind to the next frame and call the stop function
again.

_URC_END_OF_STACK: In order to allow _Unwind_ForcedUnwind to
perform special processing when it reaches the end of the stack,
the unwind runtime will call it after the last frame is rejected,
with a NULL stack pointer in the context, and the stop function
must catch this condition (i.e. by noticing the NULL stack pointer).
It may return this reason code if it cannot handle end-of-stack.

_URC_FATAL_PHASE2_ERROR: The stop function may return this code
for other fatal conditions, e.g. stack corruption.

If the stop function returns any reason code other than _URC_NO_REASON,
the stack state is indeterminate from the point of view of the caller
of _Unwind_ForcedUnwind. Rather than attempt to return, therefore, the
unwind library should return _URC_FATAL_PHASE2_ERROR to its caller.

Example: longjmp_unwind()

The expected implementation of longjmp_unwind() is as follows.
The setjmp() routine will have saved the state to be restored
in its customary place, including the frame pointer. The
longjmp_unwind() routine will call _Unwind_ForcedUnwind with
a stop function that compares the frame pointer in the context
record with the saved frame pointer. If equal, it will restore
the setjmp() state as customary, and otherwise it will return
_URC_NO_REASON or _URC_END_OF_STACK.

...."

> > plus Ex.Specs 'fencing' aside, for a moment]:
>

> Again, it's very unclear what you mean.

See "The behavior is undefined in the following cases" above.

[...]
> I don't know what Herb's answer would be, but IMO it's not really possible
> to protect anyone from most "really bad things", except by carefully coding
> to avoid them. If you have better ideas about this, I guess the world would
> love to know them.

Well, with "protection" I meant something that would prevent the
propagation [out of throw() routines, to begin with] of anything
raised [and left 'unhandled' or re-raised] due to "really bad
things" or whatever.

IOW, I believe strongly that a) TWO-PHASE exception processing
shall be declared MANDATORY[1] by the C++ standards committee
and b) exception specifications shall be revised/fixed so that
they shall NOT require unneeded/harmful unwinding on ex.specs.
violation [way up to that implicit 'catch(...)' handler that's
meant to invoke std::unexpected(); that should better be done
>>AT THROW POINT<< in the next version of C++, IMNSHO].

[...]
> > http://www.m-w.com [and alike; I have a local replica] helps as well.
>
> Is "oll korrect" in there?

Yep [indirectly, though]:

< from site referenced above >

"....
3 entries found for OK.
To select an entry, click on it.
OK[1,adverb or adjective]OK[2,noun]OK[3,transitive verb]

Main Entry: 1OK
Variant(s): or okay /O-'kA, in assenting or agreeing also 'O-"kA/
Function: adverb or adjective
Etymology: abbreviation of oll korrect, facetious alteration of all correct
^^^^^^^^^^^
Date: 1839
: ALL RIGHT"

;-)

regards,
alexander.

[1] Yes, [presuming that it's doable] that would add to the run-time
overhead of all those archaic setjmp/longjmp 'C-macro' exceptions;
but heck... 'big deal'.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

White Wolf

unread,
Feb 8, 2003, 1:12:27 PM2/8/03
to
"Arnold Hendriks" wrote:
> This is not comp.lang.c++ - the OP was asking about his existing
system,
> and on some existing systems (and especially with Visual C++, about
which
> the OP explicitly asked), you /have/ to deal with catch(...)
interfering
> with correct program behaviour when SEs or whatevers are thrown.
>
> It's fine that catch(...) does not catch non-C++ exceptions on a
conforming
> compiler, but in real life, most people on Windows aren't working with
a
> conforming compiler, and have to deal with catch(...) being broken.
Ignoring
> the problem by hiding behind the C++ standard often does not help,
because
> switching compilers is often impossible or too expensive.

That is why I have mentioned that all exceptions require specific
handling are better be handled. Please do not expect me to list them
for all possible platforms. My point was that in general catch(...) can
avoid your server from stopping on a malicious request etc. But I
think this discussion leads much further than C++ catch, into the
territory of security and possible "paranoid mode" for server processes
as an active protection against attacks.

WW


White Wolf

unread,
Feb 8, 2003, 1:15:46 PM2/8/03
to

"Alexander Terekhov" wrote:
>
http://groups.google.com/groups?selm=c29b5e33.0202161915.3cd77b6f%40post

ing.google.com
> (Subject: Re: Guru of the Week #82: Solution)

Sorry, I have no strength left to read everything, I have set you other
two replies undread and I will read them when my cold is getting any
better. About the above link: it seems we have the same feeling about
that very "paranoid mode". :-)

WW


Alexander Terekhov

unread,
Feb 8, 2003, 1:22:16 PM2/8/03
to

Except that you seem to think that catch(...)-everything can
help you to make the system "more robust". But it can't help
you. It can only HURT you.

< C++ Standard Core Language Active Issues, Revision 22 >

"Bjarne Stroustrup: I strongly prefer to have the call to
std::terminate() be conforming. I see std::terminate() as
a proper way to blow away "the current mess" and get to the
next level of error handling. I do not want that escape to
be non-conforming - that would imply that programs relying
on a error handling based on serious errors being handled
by terminating a process (which happens to be a C++ program)
in std::terminate() becomes non-conforming. In many systems,
there are - and/or should be - error-handling and recovery
mechanisms beyond what is offered by a single C++ program."

regards,
alexander.

Alexander Terekhov

unread,
Feb 8, 2003, 2:27:30 PM2/8/03
to
Wolf, I suggest that [once your cold will get any better] you should
[also] read the following "A-B-C":

Alexander Terekhov wrote:
[...]


> http://groups.google.com/groups?selm=3D711160.2DE3FC09%40web.de
> (Hi There! Greetings from the ``yellow zone.'')

A) http://groups.google.com/groups?selm=3DF5078B.12F058B1%40web.de

B) http://groups.google.com/groups?threadm=3DF7647E.C84435BC%40web.de

C) < Forward Inline >

-------- Original Message --------
From: Niklas Matthies <comp.lang.c++.mod...@nmhq.net>
Newsgroups: comp.lang.c++.moderated
Subject: Re: C++ stack overflow and exception safety
Date: 8 Feb 2003 06:33:36 -0500

Sorry for the late follow-up, unfortunately my spare time has become
rather limited.

On 2002-12-24 09:27, David Abrahams <da...@boost-consulting.com> wrote:
> Niklas Matthies <comp.lang.c++.mod...@nmhq.net> writes:
>> On 2002-12-23 11:39, David Abrahams <da...@boost-consulting.com> wrote:
>>> Niklas Matthies <comp.lang.c++.mod...@nmhq.net> writes:
>>>
>>> Ooh, I *deeply* disagree with that part. Stack space is very
>>> different from both of those resources because while they are always
>>> explicitly requested, stack space is not.
>>
>> I consider a declaration of a local variable to be an explicit
>> request of stack space
>
> Based on what?

Based on the fact that local variables take up storage space.
The (defining) declaration of a local variable causes storage space to
be reserved for the lifetime of the variable. The declaration makes
this explicit, compared with the implicitness in the case of (say)
temporaries.

> There's nothing in the standard which makes that association.

3p5: "A variable is introduced by the declaration of an object. The
variable's name denotes the object."
1p8: "An object is a region of storage. An object is created by a
definition (3.1), by a new-expression (5.3.4) or by the implementation
(12.2) when needed."

> FWIW, your implementation almost certainly allocates stack for all
> local variables at once, when the function is entered.

Certainly. The situation is quite similar for heap allocation, where
implementations usually allocate heap space in chunks of a certain page
size, although a program generally only requests parts of it gradually
bit by bit. (Well, object by object.)

>> as well as a function call (due to the argument declarations).
>
> What about void f()?

No explicit request here.

> In practice, you will need stack space for a return address.

True.

> What about adding two integers? What about multiplying two longs? On
> some real architectures this may cause a function call. What about
> floating point operations? What about a pointer dereference?

Again, no explicit request.

> My point is that which operations need to allocate stack is completely
> non-portable.

My point is that there needs to be a well-defined contract between
program and implementation with regard to the stack space the program
requires.

It is obvious that the contract cannot require the implementation to
unconditionally provide all stack space the execution of the program
requires, for the same reason that we cannot expect the implementation
to provide all heap memory the program requires.

And for the same reason that we want new to throw or return a null
pointer upon failure to allocate storage space, instead of undefined
behavior, we should want some defined behavior upon exhaustion of
stack space.

> My other point is that if you define stack overflow to throw an
> exception, then portably speaking, any operation might throw.

The trick, of course, is to reduce these "throwing opportunities" to
those points in the execution of the program where we are okay with an
exception being thrown.

This means that the stack space needed between one such point and the
next, or some reasonably close upper bound thereof, needs to be known
at the first point, so that it can be preallocated there to safely
execute up to the next point.

The big question is: Can we achieve this in all situations were we
require (or desire) it? This is what I think is interesting and
worthwhile to explore.

>> This will become even more true once VLAs are introduced in C++.
>
> It is by no means a foregone conclusion that VLAs will be added.

Sure, 'once' can be never.

>> And local variables are really just VLAs whose size is statically
>> known. ;)
>
> In some cultures, a man is just a long pig ;-)

Uh, well. :)

>> One can argue that temporaries/sub-expressions and the space for the
>> function's return address are not explicitly requested, but of
>> course they are at the assembler level, and C/C++'s syntax merely
>> provides notational convenience to make the request implicit.
>
> There's no requirement in the C++ standard that there even is an
> assembler level. But even if there were, so what?

Well, the request are still there. Someone needs to be responsible for
the situation were they cannot be fulfilled. In the world of the C++
standard, there are only two candidates for that, the implementation
or the program, at least from the program's (and hence the programmer's)
point of view. Currently no one is responsible.

>> Furthermore, is appending a character to a file really a more explicit
>> request of storage space than using a nested expression or calling a
>> function? It's all a matter of programmer awareness.
>
> IMO, it's a matter of documented behavior. It's important to be able
> to reason about the effects of your program. There's no problem
> knowing whether an expression can throw an exception in standard C++,
> if it's properly documented.

My concern is exactly that, formally speaking, you cannot reason about
the effects of your program if stack overflow can cause undefined
behavior unpredictably at virtually any point of execution.

> If you say that you have to be aware that /any/ operation can throw,
> you might as well give up on error recovery altogether. If we
> introduce a concept like "anything might throw, but only in case of
> stack overflow and that's unlikely", we have to think about
> probabilities when we're reasoning about program correctness... a cost
> which is, IMO, not worth it.

First, as should have become clear, I'm certainly not proposing a
Java-esque solution where anything can throw.

Rather, quite similar as you would be unhappy if anything could throw,
even if only in unlikely situations, I am unhappy that currently
anything can cause undefined behavior, even if only in those very same
unlikely situations.

>>> You can never know portably when your implementation will request more
>>> stack space, which is part of what makes it so hard to handle as an
>>> error condition.
>>
>> See it this way: The program requests stack space from the (C++)
>> implementation.
>
> It does not. There is nothing you can write which is guaranteed to
> "request stack space". If anything, the C++ implementation requests
> stack space from the platform.

The program causes objects of automatic storage duration to be
created. This is what I am calling "requesting stack space", for
the purpose of emphasizing that it's something that the implementation
does on a very specific behalf of the program, rather than out of some
arbitrary whim. Hence the program cannot simply deny any responsibility
for that and blame the implementation.

But currently, the program is not given any means to assume this
responsibility in the case of stack space exhaustion, and neither
is it given any means to prevent it. This is like being death
sentenced without having been given any choice about committing the
criminal offense.

>> If an implementation can not guarantee to be able to fulfill that
>> request, it should provide some means for the program to sensibly
>> react to that situation.
>
> I would not want to impose that requirement on implementations without
> paged virtual memory.

In what respect is virtual memory vital here?

[...]
>>> But I'm glad you brought it up, because I think I agree with your
>>> description of undefined behavior. I can't find any justification in
>>> the standard for calling stack overflow "undefined behavior". The
>>> only place in the standard that can account for stack overflow,
>>> AFAICT, is this sentence from 1.4:
>>>
>>> --- If a program contains no violations of the rules in this
>>> International Standard, a conforming implemen- tation shall, within
>>> its resource limits, accept and correctly execute 3) that program.
>>
>> Yes. In my opinion it would be more sensible (with regard to the
>> current state of the language) for an implementation to formally
>> become non- conforming when it runs out of stack space since stack
>> space is something that the standard forces programs to basically
>> take for granted.
>
> Uh-oh:
>
> "that's not the usual meaning of non-conformance"
>
> Conformance is not (supposed to be) a dynamic property of an
> implementation.

Well, I don't see a great difference between becoming non-conforming
or just discovering its non-conformance. By "becomes non-conforming",
I basically mean "stops to exhibit conforming behavior". After all,
that is the only thing what matters in the end.

-- Niklas Matthies

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

regards,
alexander.

Hillel Y. Sims

unread,
Feb 9, 2003, 4:59:41 PM2/9/03
to
"White Wolf" <wo...@freemail.hu> wrote in message
news:b22eqv$9pa$1...@phys-news1.kolumbus.fi...

>
> You are kidding yes? The MicroSoft propiatery C-style
structured
> exceptions are not part of the standard, so if I am right,
there is no
> way to quote the standard. But I am patiently waiting for
your chanpter
> and verse telling that non-C++ exceptions should and can be
caught by a
> C++ try clause in a standard conforming implementation.
>

Hmm..

15.3 Handling an exception [except.handle]
6) "A ... in a handler's exception-declaration functions
similarly to ... in a function parameter declaration; it
specifies a match for any exception. [..]"

I really cannot find anything else here that states that "any
exception" *must* have been thrown only in a synchronous context
and only by a "throw <xyz>" statement (throw-expression).
(Besides -- why couldn't the SEH-type stuff (Windows or any
other OS) really be implemented internally in C++ code with
inaccessible typenames by the OS anyhow?)

Hillel Y. Sims

unread,
Feb 9, 2003, 5:30:43 PM2/9/03
to
"White Wolf" <wo...@freemail.hu> wrote in message
news:b22fbb$ad3$1...@phys-news1.kolumbus.fi...

> "Hillel Y. Sims" wrote:
> > This is not comp.std.c++... I can talk about any kind of
> > exception I want. :-)
>
> As long as they are valid C++ exceptions, thrown by the C++
throw
> keyword - yes.

Can you please point out where in the Standard it states that
exceptions caught by catch(...) must be "valid C++ exceptions,
thrown by the C++ throw keyword"? (Please reference my other
post from today -- re: 15.3/6 of C++ Standard)

> >
> > All the world's not Unix. Welcome to VMS / Windows.
>
> All the world is not Windows. Welcome to UNIX. You have
stated
> something to be generally true, which isn't.

The assumption that catch(...) will only catch "harmless to
swallow" exceptions is faulty in general. It may be true on some
Unix systems (in terms of stuff like access violations, but even
then not necessarily, if you don't fully take into account
potential for thread exceptions or any other exceptions not
really meant to be ignored), but it is not true across all OSes.

>
> BTW I did tell that any exception requires handling in your
environment
> has to be handled before the catch(...), but for the sake of
quarrel
> both you and Alexander seem to ignore that comment.

If you have fully handled "any exception [that] requires
handling in your environment [..] before the catch(...)" then
what else are you possibly trying to catch? Is it not probably
then that anything that has not already been handled is
*unexpected* and therefore should not be caught/swallowed?

> > If you already caught everything you were supposed to, then
why
> > do you want to bother with catch(...) anyhow?
>
> Caught everything the _environment_ might throw. Everything,
which
> cannot or better be not be ignored it thrown by the
_environment_.
> Kapis?

Not really -- I've read that a few times and still don't quite
understand it.. :-)


> > > And ray that no other exception will come, because then
you
> > crash!
> >
> > That's kind of the point..
>
> OK. So have a nice drive at 2am to your server rooms to
figure out why
> does your server keep reastarting in every second.

I have a cable modem and VPN -- I can debug from home. ;-) And I
will much prefer to see a nice core dump log pinpointing exactly
what caused the crash and where it occurred and be able to fix
it quickly and not have to worry about it again. This is usually
a far better alternative than swallowing unknown errors and then
eventually your server crashes anyhow (maybe at 3:30am) after
also corrupting important data files, because the earlier hidden
access violation had corrupted the program state and then some
random operation that seems to be completely harmless fails,
except that now the cause of the failure is extremely difficult
to track down (because the real problem occured 1.5hrs earlier
in a totally different point in the code), and so you get
sporadic crashes and data corruption in your program which may
take weeks to debug.

Since there is really no such thing as bug-free softtware
(except the code that I write ;-), I prefer to have the crash
occur as soon as possible and avoid data corruption.

> Just because you
> could have ignored an exception (ignore here means: not let it
crash you
> and eg: drop the last transaction what have caused it)

As has been said previously, if you catch well-known expected
base classes, you can safely ignore unhandled exceptions and
clean up and not let it crash your program. catch(...) is *not
safe* because it will also catch (and hide) stuff like thread
exceptions (which should be propagated) and access violation
exceptions (on many systems).

> but you have
> decided to not place that ctach(...) there. So one 12 years
old who has
> figured out what packet to send to you keeps you server down -
without
> even flooding...

Can you explain how catch(...) can help alleviate any
difficulties caused by a buffer overflow attack against your
program?

James S. Rogers

unread,
Feb 10, 2003, 12:17:38 AM2/10/03
to
"Hillel Y. Sims" <use...@phatbasset.com> wrote in message
news:nEA1a.213850$HG.36...@news4.srv.hcvlny.cv.net...

> Can you explain how catch(...) can help alleviate any
> difficulties caused by a buffer overflow attack against your
> program?

Buffer overflows should never be hidden by a catch-all.
Buffer overflows should always crash your program.
Crashing is much better than the alternatives.

In C++ your buffers (for safety reasons at least) should
always be implemented as classes with built in overflow
detection. Using raw C-style arrays for C++ buffers is
just not safe due to the well known weaknesses of the
C array paradigm.

Jim Rogers


White Wolf

unread,
Feb 11, 2003, 11:54:26 AM2/11/03
to
"Alexander Terekhov" wrote:
> Okay. One more try. No link this time. Copy&paste, instead. And, BTW,
> the "totally busted" {C++}ABI specification can be found here:

What I have managed to understand from this long discussion is that the
very C++ ABI you refer to is a big mess. There is more undefined (and
complex) behavior in it than in my ex, and that's something.

WW aka Attila


White Wolf

unread,
Feb 11, 2003, 11:59:31 AM2/11/03
to
"Alexander Terekhov" wrote:
> Subject: exception handling -- forced unwinding

I dunno what this forced unwinding is - but AFAIK there is either a
crash (terminate->abort) if there is no handler (so that one can see
what went wrong) or the exception must be properly handled. In between
the exception is caught at a level to provide unwinding and some
cleanup/error reporting and then it is rethrown to cause the crash- but
this one is already something which might even be impossible to do.
IMHO any other approach is doomed with complexity and it is opposite to
the exception fundamentals of C++. This is rather a feeling than
something I could immediately prove with a mathemathical precision.

WW aka Attila


White Wolf

unread,
Feb 11, 2003, 12:53:54 PM2/11/03
to
"Alexander Terekhov" wrote:
> [...]
> > http://groups.google.com/groups?selm=3D711160.2DE3FC09%40web.de
> > (Hi There! Greetings from the ``yellow zone.'')
>
> A) http://groups.google.com/groups?selm=3DF5078B.12F058B1%40web.de

Well, my interpreter fails already here. These kinds of pthread
operations we (I) do not use/never used. :-( Actually in my environment
"shutting down" a thread is done by application level means. Basically
(putting it a very simple way) you can imagine a kind of cooperating
multithreading. The threads do very short tasks in reaction to events
and while they do those they cannot be interrupted. OK, they can be by
the OS if I have less CPUs than threads - but they cannot be cancelled
in any way. Of course, it requires that those events and their handling
to be well choosen so that the time spent on handling is short - as well
as there is little overhead. I think the idea is very well described by
this CUJ article: http://www.cuj.com/current/0303b.htm

(No pun intended by posting a link, I just think it is a really good
description.)

> B) http://groups.google.com/groups?threadm=3DF7647E.C84435BC%40web.de

This one I seem to understand, except your except-cancel-safe example.
I guess it is a pseudo-code. I pseudo understood it. :-) BTW it is
very impolite of pthread_cancel to cancel at any instruction. There can
be (many) operations which must not be interrupted. Even if the thread
is being cancelled. Communication to an external entity with states
springs into mind. Not knowing if the last operation (like writing to
the memory of a device) is done or not may have to trigger a long
recovery process... Anyways if a C++ constructor is cancelled after
memory is allocated (and the cancellation does not happen as a
full-right C++ exception) the memory leak is there. Well, it seems to
be a pretty dangerous thing to do (to cancel a thread).

> C) < Forward Inline >


> >> I consider a declaration of a local variable to be an explicit
> >> request of stack space
> >
> > Based on what?
>
>Based on the fact that local variables take up storage space.
>The (defining) declaration of a local variable causes storage space to
>be reserved for the lifetime of the variable. The declaration makes
>this explicit, compared with the implicitness in the case of (say)
>temporaries.

IMHO it is still different from explicit resource allocation. Eg.: many
compilers acquire the required _maximum_ stack space on _entering_ the
function. Meaning that you have no means to know when will the
"allocation" of that stack space happen. In this way IMHO one of the
major requirements of explicit allocation - it happens when you ask for
it - is gone.

Second difference is: a failing explicit allocation has standard means
to report failure. IIRC there is no standard way in C or C++ to report
stack allocation failure.

So in an explicit allocation you use an allocator construct, at that
point in the code the system tries to allocate the resource, and failure
to do so results in an error code returned or an exception thrown: both
defined in the standard.

One could say that the standard choose the convenient silence about this
topic. :-) Since IIRC the C++ Standard does not require even the
existence of a stack. :-)))) AFAIK Sparc does not have a conventional
stack (rather a huge set of registers). Well, I would have a rather
hard time to come up with an architecture not using a stack or something
which works like a stack and still run C++ code. :-)

>And for the same reason that we want new to throw or return a null
>pointer upon failure to allocate storage space, instead of undefined
>behavior, we should want some defined behavior upon exhaustion of
>stack space.

This is actually something I can completely agree with. Requiring
throwing of a standard C++ exception seems to be a good way to approach
it. The real trouble here is that whatever one tries to define here
would bring with in restrictions on compiler/platform implementations.
Not to mention that in such a case making no-throw functions can become
a nightmare. Since the exception might be thrown at the call - you did
not even enter the function yet!

>My concern is exactly that, formally speaking, you cannot reason about
>the effects of your program if stack overflow can cause undefined
>behavior unpredictably at virtually any point of execution.

You have a point here. It seems it is a work waiting to be done. And
it definitely is a non-trivial thing to design. :-(

>Rather, quite similar as you would be unhappy if anything could throw,
>even if only in unlikely situations, I am unhappy that currently
>anything can cause undefined behavior, even if only in those very same
>unlikely situations.

Completely agreed. I mean I agree with you on this point.

>But currently, the program is not given any means to assume this
>responsibility in the case of stack space exhaustion, and neither
>is it given any means to prevent it. This is like being death
>sentenced without having been given any choice about committing the
>criminal offense.

Hungary 1956-1968...

It seems that the standard chooses the way we call ostrich-politics:
pretend that the problem is not there. Unfortunately in our case that
means that by using standard C++ it is basically impossible to write
life-critical applications. It does not matter how much care you take,
you won't ever be able to recover from a stack space exhaustion. :-(

WW aka Attila


James S. Rogers

unread,
Feb 11, 2003, 5:25:17 PM2/11/03
to
"White Wolf" <wo...@freemail.hu> wrote in message
news:b2bd5g$3hg$1...@phys-news1.kolumbus.fi...

> It seems that the standard chooses the way we call ostrich-politics:
> pretend that the problem is not there. Unfortunately in our case that
> means that by using standard C++ it is basically impossible to write
> life-critical applications. It does not matter how much care you take,
> you won't ever be able to recover from a stack space exhaustion. :-(

This problem is not unique to C++. Stack exhaustion is a serious error
in any system, and can be fatal in lifte-critical systems. The best
approach I have seen for safety critical software is the set of rules
and practices defined for SPARK. SPARK uses a well defined subset
of the Ada language. That subset prohibits dynamic allocation/deallocation
of objects, including thread objects. One of the goals, and effects, of
SPARK is that it is possible to statically prove many aspects of code
correctness.

The C++ standard does not explicitly address threading issues.
This is not an attempt to avoid an issue. It is merely a statement
that C++ provides no standardized rules concerning threading.
Threaded applications have a tendency to consume stack space.
Each thread requires an incremental amount of stack space.
When designing a threaded application on a system with limited
stack space you must account for the consumption of each thread.
This is not an issue that can be controlled by the C++ standard.
It is just a fact of life concerning threads, much like the need
to provide mutex locking on shared data is common to all
threaded applications, regardless of the language used.

I think many people will recognize that I am not a strong
proponent of C++ usage. I do not think that the C++ standard
can be blamed for its lack of control over stack usage by
threads. It is best if concerns and complaints are correctly
focused on the root causes. The root cause of thread stack
space exhaustion is not a weakness of the C++ standard.
It is a design issue for threads in general.

Jim Rogers


Alexander Terekhov

unread,
Feb 12, 2003, 7:31:52 AM2/12/03
to

White Wolf wrote:
[...]

Frankly, I'm unimpressed: to begin with, the fellow doesn't seem to
know what "a monitor" is.

>
> (No pun intended by posting a link, I just think it is a really good
> description.)
>
> > B) http://groups.google.com/groups?threadm=3DF7647E.C84435BC%40web.de
>
> This one I seem to understand, except your except-cancel-safe example.
> I guess it is a pseudo-code. I pseudo understood it. :-) BTW it is
> very impolite of pthread_cancel to cancel at any instruction. There can
> be (many) operations which must not be interrupted. Even if the thread
> is being cancelled. Communication to an external entity with states
> springs into mind. Not knowing if the last operation (like writing to
> the memory of a device) is done or not may have to trigger a long
> recovery process... Anyways if a C++ constructor is cancelled after
> memory is allocated (and the cancellation does not happen as a
> full-right C++ exception) the memory leak is there. Well, it seems to
> be a pretty dangerous thing to do (to cancel a thread).

Try again. You seem to have missed the key point I was trying to
make: there should be another type of exception safety [that shall
be "enforced" by the language] -- async-cancel-safety. Unless you
fully understand this, don't even think of using async.cancel --
PTHREAD_CANCEL_ASYNCHRONOUS cancelability type; stick to the
"deferred" default or just don't use thread cancelation at all.
(it's broken on many C++ implementations due to "forced unwinding"
silliness; I mean problems(*) with respect to rather popular,
unfortunately, catch(...)-beast).

regards,
alexander.

(*) http://groups.google.com/groups?threadm=3D8EEE36.C164536D%40web.de
("Subject: "PJP doesn't seem to care" ;-)" )

White Wolf

unread,
Feb 12, 2003, 2:20:04 PM2/12/03
to
"James S. Rogers" wrote:
> > life-critical applications. It does not matter how much care you
take,
> > you won't ever be able to recover from a stack space exhaustion. :-(
>
> This problem is not unique to C++. Stack exhaustion is a serious error
> in any system, and can be fatal in lifte-critical systems.
snip

> The C++ standard does not explicitly address threading issues.
> This is not an attempt to avoid an issue. It is merely a statement
> that C++ provides no standardized rules concerning threading.
> Threaded applications have a tendency to consume stack space.
snip

Sorry - I am in a rush so my answer will be short and will sound harsh
but it is not meant to be.

This is a Red Herring. Threads have nothing to do with the possibility
of stack space exhaustion. It can happen in non-threaded applications
as well. Therefore I take this argument as mute and keep my opinion
that it makes the C++ language weaker that it does not provide standard
means of stack space exhaustion detection and recovery. While it I
understand that from this point on I am not anymore on-topic for this
NG - sorry for that.

WW aka Attila


White Wolf

unread,
Feb 12, 2003, 2:27:03 PM2/12/03
to
"Alexander Terekhov" wrote:
> [...]
> > this CUJ article: http://www.cuj.com/current/0303b.htm
>
> Frankly, I'm unimpressed: to begin with, the fellow doesn't seem to
> know what "a monitor" is.

Hm. I wonder how did he wrote the article. Does he use a TFT instead?
;-) Anyways I 100% agree with the "clean approach" he suggests. In my
short life if I can choose between trying to teach 50+ programmers to
know how to program thread safe (while knowing even I don't know the
topic - only to the level to realize I don't know it) and between
getting 3 who can do a framework (like the one described by the article)
I would certainly go for what's behind door #2.

> > > B)
http://groups.google.com/groups?threadm=3DF7647E.C84435BC%40web.de


>
> Try again. You seem to have missed the key point I was trying to
> make: there should be another type of exception safety [that shall
> be "enforced" by the language] -- async-cancel-safety.

OK. I am going away to Stockholm up to 18th (it might change) so I may
not see it... but I still ask. You mean that the language would be able
to define async-cancel-safe regions (regions not to be interrupted? Or
to somehow mix the async-cancel properly with the C+= exceptions?

> Unless you
> fully understand this, don't even think of using async.cancel --
> PTHREAD_CANCEL_ASYNCHRONOUS cancelability type; stick to the
> "deferred" default or just don't use thread cancelation at all.

I go for this option. :-) IMHO the idea of application level stopping
is clean, simple and good enough for what we use it. By good enough I
do not mean acceptable but perfect.

> (*) http://groups.google.com/groups?threadm=3D8EEE36.C164536D%40web.de
> ("Subject: "PJP doesn't seem to care" ;-)" )

Don't even remind me :-)

WW


Alexander Terekhov

unread,
Feb 12, 2003, 3:07:31 PM2/12/03
to

White Wolf wrote:
[...]

> not see it... but I still ask. You mean that the language would be able
> to define async-cancel-safe regions (regions not to be interrupted? Or
> to somehow mix the async-cancel properly with the C+= exceptions?

http://groups.google.com/groups?selm=3DF7647E.C84435BC%40web.de
(Subject: Re: C++ stack overflow and exception safety)

http://groups.google.com/groups?selm=3C926C82.AD56845D%40web.de
(Subject: Re: C++ and threads)

"// 'safe' async-cancel/bool expected_exception< cancel_e >()
'illustration'

void operation();
blabla another_operation( ...blablabla... ) async_cancel_safe;
bool yet_another_operation() throw();

...."

regards,
alexander.

James S. Rogers

unread,
Feb 12, 2003, 9:20:04 PM2/12/03
to
"White Wolf" <wo...@freemail.hu> wrote in message
news:b2e6lp$fa3$1...@phys-news1.kolumbus.fi...

I see your point.

You can certainly exhaust a stack in a highly recursive single
threaded application. There are other dependable ways to
exhaust a stack, including declaring VERY large stack-based
variables or constants.

I guess I expect stack usage monitoring to be provided by
external tools such as profiling tools. Any language-defined
tools for this would have to work across all combinations of
operating systems and hardware.

Jim Rogers


Hillel Y. Sims

unread,
Feb 12, 2003, 10:32:13 PM2/12/03
to
"Alexander Terekhov" <tere...@web.de> wrote in message
news:3E4A3EB8...@web.de...

> (it's broken on many C++ implementations due to "forced
unwinding"
> silliness; I mean problems(*) with respect to rather popular,
> unfortunately, catch(...)-beast).
>

http://www.cuj.com/experts/2104/alexandr.htm

Hillel Y. Sims

unread,
Feb 12, 2003, 10:35:07 PM2/12/03
to
"White Wolf" <wo...@freemail.hu> wrote in message
news:b2bd5g$3hg$1...@phys-news1.kolumbus.fi...

> This one I seem to understand, except your except-cancel-safe
example.
> I guess it is a pseudo-code. I pseudo understood it. :-) BTW
it is
> very impolite of pthread_cancel to cancel at any instruction.
There can
> be (many) operations which must not be interrupted. Even if
the thread
> is being cancelled. Communication to an external entity with
states
> springs into mind. Not knowing if the last operation (like
writing to
> the memory of a device) is done or not may have to trigger a
long
> recovery process... Anyways if a C++ constructor is cancelled
after
> memory is allocated (and the cancellation does not happen as a
> full-right C++ exception) the memory leak is there. Well, it
seems to
> be a pretty dangerous thing to do (to cancel a thread).

Default mode of pthread cancellation is synchronous
("deferred"), operations cannot be interrupted at arbitrary
instructions (unless the programmer specifically requests it -
asynchronous cancellation).

>
> It seems that the standard chooses the way we call
ostrich-politics:
> pretend that the problem is not there. Unfortunately in our
case that
> means that by using standard C++ it is basically impossible to
write
> life-critical applications. It does not matter how much care
you take,
> you won't ever be able to recover from a stack space
exhaustion. :-(
>

I was going to say you ought to just stick with Java then, since
everything is heap-based, but even there is still some stack
used for function calls, so I guess you can run out too.. What
does Java do when you run out of stack? ;-)

Is there any language environment where there are well-defined
semantics for handling stack-exhaustion?

White Wolf

unread,
Feb 12, 2003, 11:50:04 PM2/12/03
to
"James S. Rogers" wrote:
> I guess I expect stack usage monitoring to be provided by
> external tools such as profiling tools.

The troouble is the old one: it is impossible to test all cases!

> Any language-defined
> tools for this would have to work across all combinations of
> operating systems and hardware.

That is the whole idea. :-) To have standard means to detect and
recover. As I have written in another post: it is a non-trivial design
job what needs to be done here. :-(

WW


White Wolf

unread,
Feb 12, 2003, 11:54:46 PM2/12/03
to
"Hillel Y. Sims" wrote:
> Default mode of pthread cancellation is synchronous
> ("deferred"), operations cannot be interrupted at arbitrary
> instructions (unless the programmer specifically requests it -
> asynchronous cancellation).

Well, there is still the what if for handling the other situation in
C++. IMHO in C you have to handle any cleanup by hand-made constructs,
but in C++ it gets more difficult. :-(

> I was going to say you ought to just stick with Java then, since
> everything is heap-based, but even there is still some stack
> used for function calls, so I guess you can run out too.. What
> does Java do when you run out of stack? ;-)

I dunno. I run out of the room if I am asked to do Java. :-)

> Is there any language environment where there are well-defined
> semantics for handling stack-exhaustion?

I have no idea. If there is none, that is sad.

WW


Alexander Terekhov

unread,
Feb 13, 2003, 3:30:35 AM2/13/03
to

"Hillel Y. Sims" wrote:
>
> "Alexander Terekhov" <tere...@web.de> wrote in message
> news:3E4A3EB8...@web.de...
> > (it's broken on many C++ implementations due to "forced unwinding"
> > silliness; I mean problems(*) with respect to rather popular,
> > unfortunately, catch(...)-beast).
> >
>
> http://www.cuj.com/experts/2104/alexandr.htm

Mama mia!

http://lists.boost.org/MailArchives/boost/msg36228.php
([boost] Re: Basic guarantee and synchronized multiple updates.)

http://groups.google.com/groups?selm=3CC434E6.8FE3804C%40web.de
http://groups.google.com/groups?selm=3CC5E503.32B6DB41%40web.de
http://groups.google.com/groups?selm=3CC69ED3.3D5E3B99%40web.de
(Subject: Re: NDEBUG for range checks?)

regards,
alexandEr.

--
http://groups.google.com/groups?selm=3E43AF4A.B9B8B947%40web.de

Alexander Terekhov

unread,
Feb 13, 2003, 4:09:03 AM2/13/03
to

White Wolf wrote:
[...]

> Well, there is still the what if for handling the other situation in
> C++. IMHO in C you have to handle any cleanup by hand-made constructs,
> but in C++ it gets more difficult. :-(

http://groups.google.com/groups?selm=3DB6DBD7.34704050%40web.de
(Subject: Re: Library Safety (was: Homework, 100$ for 12 toy programs))

>
> > I was going to say you ought to just stick with Java then, since
> > everything is heap-based, but even there is still some stack
> > used for function calls, so I guess you can run out too.. What
> > does Java do when you run out of stack? ;-)
>
> I dunno.

Ok, I "no": <http://groups.google.com/groups?selm=3D08A049.6850244E%40web.de>.
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Concepts.doc.html#24614
(2.16.1 The Causes of Exceptions)

regards,
alexander.

0 new messages