Topic: Threads: Exceptions in Signal-Handlers
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1998/06/11 Raw View
Valentin Bonnard <bonnardv@pratique.fr> writes:
|> Petter Urkedal <petter@matfys.lth.se> writes:
|>
|> > Christian Millour wrote:
|> > >
|> > > AFAIK, FDIS C++ is unaware of threads, and posix threads are unaware
|> > > of C++. So there is no portable way. Different compiler vendors have
|> > > different (typically per platform/os) solutions.
|> >
|> > But C++ is aware of signals.
|>
|> Not really. There is nothing you can do in a signal handler
|> (I mean nothing useful).
|>
|> I don't even understand why signal is there in the standard.
Probably so that abort() could be defined:-).
Seriously: abort() is a useful function, with well defined
semantics. Part of those semantics, in the UNIX world where C evolved,
were that an abort() could be intercepted by catching SIGABRT. I
suspect that the C standards committee felt that 1) they couldn't not
define abort(), and 2) they couldn't define it with semantics different
than those in UNIX.
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient e objet --
-- Beratung in objektorientierter Datenverarbeitung
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/29 Raw View
What happens if an exception is thrown and not caught inside a
signal hander? I could not find any answer in the Nov96-Draft.
However, signals is a part of the C++ standard, as inherited
from C.
In my opinion, it is very important that the exception is
rethrown in the code of the thread which received the signal.
This makes it possible to cancel a thread from another thread,
and assuring that all destructors in the cancelled tread is
called.
If execptions are not rethrown, we have the option to
* insert some I_am_here() check-points all around the code, or
* discard the C++ style of programming, making cleanup-
handers, or
* never cancel threads, or
* do some magic I'm not aware of.
Someone knows what FDIS says explicitely or between the lines?
How are we supposed to cancel threads in C++?
Petter.
The following code will check how your compiler/OS works, provided
you implement send_complant(char*):
------------------------------------------------------------------
#include <csignal>
void handler(int n) { throw n; }
main() {
signal(SIGUSR1, handler);
try {
raise(SIGUSR1);
send_complaint("my.vendor@super-compiler.com");
} catch(int i) {
feel_happy();
}
}
------------------------------------------------------------------
[- http://matfys.lth.se/~petter/ -]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/29 Raw View
Petter Urkedal <petter@matfys.lth.se> wrote:
>What happens if an exception is thrown and not caught inside a
>signal hander? I could not find any answer in the Nov96-Draft.
>However, signals is a part of the C++ standard, as inherited
>from C.
The short answer is: Boom!
The long answer is that the standard only defines a very
few permitted operations in a signal handler, and throwing
is not one of them. This doesn't mean that you can't throw,
it only means that implementers aren't obliged to document
what happens if you do.
>In my opinion, it is very important that the exception is
>rethrown in the code of the thread which received the signal.
>This makes it possible to cancel a thread from another thread,
>and assuring that all destructors in the cancelled tread is
>called.
I think it is quite unlikely that any particular implementation
would do this, although any of them might do it. What is
certain is that what would happen is non-portable, and any
code you write for this case belongs in the non-portable
part of your program, where *you* are responsible to make
sure something reasonable happens, standard or no standard.
>If exceptions are not rethrown, we have the option to
>
> * insert some I_am_here() check-points all around the code, or
>
> * discard the C++ style of programming, making cleanup-
> handers, or
>
> * never cancel threads, or
>
> * do some magic I'm not aware of.
This last is it.
>Someone knows what FDIS says explicitly or between the lines?
>How are we supposed to cancel threads in C++?
That's the wrong question. The question is, how are we
supposed to cancel threads in C++ on platform X + compiler
A, and how on Y + B, and is it even possible on Z + C?
(This is a question for your compiler vendors.)
Further, is there anything similar among the answers that
can be abstracted and encapsulated so it doesn't infect
your whole program? An answer to this is bound to be
interesting to people other than yourself, so if you
make any progress, be sure to report it.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christian Millour <chris161@club-internet.fr>
Date: 1998/05/29 Raw View
Petter Urkedal wrote:
>=20
> What happens if an exception is thrown and not caught inside a
> signal hander? I could not find any answer in the Nov96-Draft.
> However, signals is a part of the C++ standard, as inherited
> from C.
There is frightfully little you can do within a signal handler.
I'd expect chaos.=20
> How are we supposed to cancel threads in C++?
AFAIK, FDIS C++ is unaware of threads, and posix threads are unaware=20
of C++. So there is no portable way. Different compiler vendors have
different (typically per platform/os) solutions.=20
Note that thread cancellation does not map directly to exception
handling. First, the `cancel' exception should not be catchable
within the cancelled thread. Second, it may have to traverse
function/method calls with trow() specifications. Apart from that
they have a lot in common and can certainly benefit from a=20
common support. But then it becomes platform dependant and I am
not holding my breath for a standard, portable solution.
--
Christian Millour mailto:chris161@club-internet.fr
Ing=E9nieur Conseil en Informatique Tel/Fax:+33 [0]1 30 21 22 80
32 rue Edouard Charton 78000 Versailles FRANCE
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/29 Raw View
Christian Millour wrote:
>
> AFAIK, FDIS C++ is unaware of threads, and posix threads are unaware
> of C++. So there is no portable way. Different compiler vendors have
> different (typically per platform/os) solutions.
But C++ is aware of signals. This could have been a backdoor for the
C++ comittee to provide a the required mechanism for canelling
threads without ever mentioning the word `thread'. The possibility
was not used.
> Note that thread cancellation does not map directly to exception
> handling. First, the `cancel' exception should not be catchable
> within the cancelled thread.
I don't agree on this one. C++ always leaves some responsibility
back to the user. In this case, to respect a thread-cancelled
exception, and clean up as quickly as possible. It could even be
very useful, as in,
f() {
some_type *p = 0;
try {
p = new some_type;
// ...
} catch(thread_cancelled&) {
if(p) delete p;
throw;
}
}
> Second, it may have to traverse
> function/method calls with trow() specifications. Apart from that
> they have a lot in common and can certainly benefit from a
> common support. But then it becomes platform dependant and I am
> not holding my breath for a standard, portable solution.
That is definitely a problem...
Petter.
--
[- http://matfys.lth.se/~petter/ -]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/29 Raw View
Nathan Myers wrote:
>
> [...] the standard only defines a very
> few permitted operations in a signal handler, and throwing
> is not one of them. This doesn't mean that you can't throw,
> it only means that implementers aren't obliged to document
> what happens if you do.
We could see it from another point of view: If we forget all
the intricate details of *implementation* of exceptions, we
realize that exceptions is a language construct -- not a system-
call; neighter a global variable. In my naive thinking I can't
help raising this question.
Nevertheless, I must agree with you. That is, because I have
some idea about a virtual machine behind the scene. But only
for this reason!
I.e. In my opinion the (draft) standard lacks the statement:
`Throwing an exception in a signal handler yields implementation
defined behaviour.'
But what a pity this fact is! (There is far more interesting
things we could do with signals-exceptions than cancelling
threads!)
NM:
> PU:
> >In my opinion, it is very important that the exception is
> >rethrown in the code of the thread which received the signal.
> >This makes it possible to cancel a thread from another thread,
> >and assuring that all destructors in the cancelled tread is
> >called.
>
> I think it is quite unlikely that any particular implementation
> would do this, although any of them might do it. What is
> certain is that what would happen is non-portable, and any
> code you write for this case belongs in the non-portable
> part of your program, where *you* are responsible to make
> sure something reasonable happens, standard or no standard.
Fair enough; then we will need a library to be ported to various
platforms. But that seems not to be possible...
NM:
> PU:
> >Someone knows what FDIS says explicitly or between the lines?
> >How are we supposed to cancel threads in C++?
>
> That's the wrong question. The question is, how are we
> supposed to cancel threads in C++ on platform X + compiler
> A, and how on Y + B, and is it even possible on Z + C?
> (This is a question for your compiler vendors.)
Yes, especially your last point -- It would be a big improvement
if the standard said: For any compiler X + any platrom Y, which
supports threads, it must be possible to cancel a thread without
violating the integrity of ctor-dtor calls in the program.
That's a modest request!
Then we can start to write sensible C++ code, and know that
it is possible to implement a given thread-interface on any
combination X+Y. As I understand it now, this possibility is
not guaranteed.
Petter.
--
[- http://matfys.lth.se/~petter/ -]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/05/29 Raw View
In article 9D04E061@matfys.lth.se, Petter Urkedal <petter@matfys.lth.se> writes:
>Nathan Myers wrote:
>>
>> [...] the standard only defines a very
>> few permitted operations in a signal handler, and throwing
>> is not one of them. This doesn't mean that you can't throw,
>> it only means that implementers aren't obliged to document
>> what happens if you do.
>
>We could see it from another point of view: If we forget all
>the intricate details of *implementation* of exceptions, we
>realize that exceptions is a language construct -- not a system-
>call; neighter a global variable. In my naive thinking I can't
>help raising this question.
>
>Nevertheless, I must agree with you. That is, because I have
>some idea about a virtual machine behind the scene. But only
>for this reason!
>
>I.e. In my opinion the (draft) standard lacks the statement:
>`Throwing an exception in a signal handler yields implementation
>defined behaviour.'
It does say that. :-) C++ includes by reference the C standard.
The ISO C standard says in section 7.7.1.1 "The signal function":
"If the signal occurs other than as a result of calling
the abort or raise function, the behavior is undefined if the
signal handler calls any function in the standard library other
than the signal function itself (with a first argument corresponding
to the signal that caused the invocation of the handler) or refers
to any object with static storage duration other than by assigning
a value to a static storage duration variable of type volatile
sig_atomic_t."
The C++ standard in section 18.7 "Other runtime support" discusses
C++ requirements on signal handlers. It defines a "POF" (plain old
function) as being one that is valid when viewed both as a C and
as a C++ function. It goes on to say that using other than a POF
as a signal handler has implementation-defined results. A function
that has a try-block, catch-block, or a throw expression is not
a POF.
> ... It would be a big improvement
>if the standard said: For any compiler X + any platrom Y, which
>supports threads, it must be possible to cancel a thread without
>violating the integrity of ctor-dtor calls in the program.
>
>That's a modest request!
Such a statement would be meaningless without good defintions
for threads and cancellation of threads. That is not a trivial
problem, given that there is little agreement on what they
mean. Sun Solaris, for example, has "processes", used to have
"light-weight processes" as an add-on, and for a while has had
"threads" built in. Solaris threads I'm sure would meet most
definitions of "thread", but it's anyone's guess whether a
process or lwp should be considered a thread in this context.
IMHO there is little point in trying to make any guarantees in
the standard without defining a thread model and specifying how
a C++ implementation must support that model. Otherwise you get
a requirement that can't be tested and so has no useful meaning.
And specifying ctor-dtor integrity wouldn't be enough. What
library functions and other operations are thread-safe? How
can a programmer tell whether a function is thread-safe?
You can't use threads in a program without being able to answer
those questions.
The C++ Committee felt it had more than enough to do without
opening that can of worms. We were all interested in the
subject, but decided to save it for another day.
---
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1998/05/30 Raw View
stephen.clamage@sun.com (Steve Clamage) writes:
>The C++ Committee felt it had more than enough to do without
>opening that can of worms. We were all interested in the
>subject, but decided to save it for another day.
In addition to the problems already mentioned,
asynchronous exceptions cause a few more:
- it is extremely difficult to write reliable programs
if *any* operation could raise an exception due to
a signal.
- the desired feature is actually quite difficult to implement,
because the same problem applies at the code generation level:
it is difficult for a compiler to generate efficient and
reliable code if any instruction could raise an exception
due to a signal.
I have it on hearsay that Java 1.0 had support for asynchronous
exceptions, but this was deprecated in 1.1, probably due to these
kinds of problems.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/30 Raw View
Steve Clamage wrote:
>
> The C++ standard in section 18.7 "Other runtime support" discusses
> C++ requirements on signal handlers. It defines a "POF" (plain old
> function) as being one that is valid when viewed both as a C and
> as a C++ function. It goes on to say that using other than a POF
> as a signal handler has implementation-defined results. A function
> that has a try-block, catch-block, or a throw expression is not
> a POF.
That clears up the subject. Thanks. I'm still using the Nov96
Draft :-|
> And specifying ctor-dtor integrity wouldn't be enough. What
> library functions and other operations are thread-safe? How
> can a programmer tell whether a function is thread-safe?
> You can't use threads in a program without being able to answer
> those questions.
In practice it seems that thread safety of libraries is taken
seriously now. And a library can be more easily modified, worked
around or even avoided than a compiler. Therefore, I would prefer
that the compiler has the required features. It can be very
difficult to work around a lack in the compiler.
> The C++ Committee felt it had more than enough to do without
> opening that can of worms. We were all interested in the
> subject, but decided to save it for another day.
I sympathize with the committee on this. On the other hand,
allowing throw in signal handers would not open a can of worm, but
rather extend the standard with a single statement. And it would,
of course, give compiler vendors another non-trivial problem.
Petter.
--
[- http://matfys.lth.se/~petter/ -]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/05/31 Raw View
Petter Urkedal <petter@matfys.lth.se> wrote:
>...allowing throw in signal handers would not open a can of worm, but
>rather extend the standard with a single statement.
Sorry, we've heard that one too many times already.
What would you expect to happen in a destructor? (The effect of
throwing from destructors in the standard library is undefined.)
How about a function that was specified with "throw()"? What if
the thread were already catching an exception when the signal came
in?
How many worms do you need? ($.02 per dozen.)
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/06/01 Raw View
Nathan Myers <ncm@nospam.cantrip.org> writes:
> Petter Urkedal <petter@matfys.lth.se> wrote:
> >What happens if an exception is thrown and not caught inside a
> >signal hander? I could not find any answer in the Nov96-Draft.
> >However, signals is a part of the C++ standard, as inherited
> >from C.
>
> The short answer is: Boom!
Nathan is right, of course, but I will insist on the fact
that you get the 'Boom!' when you throw, even if you catch
before escaping the handler:
void foo (int)
{
try {
throw "error"; // boom !
} catch (...)
{
}
}
signal (number, foo);
Actually, from the std point of view, you can
get the 'boom' here too:
void foo (int)
{
if (0)
throw "error"; // not a C feature: boom !
}
because, according to the std (and to put it simply),
signal handlers shall be written in C.
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/06/01 Raw View
Petter Urkedal <petter@matfys.lth.se> writes:
> Christian Millour wrote:
> >
> > AFAIK, FDIS C++ is unaware of threads, and posix threads are unaware
> > of C++. So there is no portable way. Different compiler vendors have
> > different (typically per platform/os) solutions.
>
> But C++ is aware of signals.
Not really. There is nothing you can do in a signal handler
(I mean nothing useful).
I don't even understand why signal is there in the standard.
> This could have been a backdoor for the
> C++ comittee to provide a the required mechanism for cancelling
> threads without ever mentioning the word `thread'.
Having a thread library in the standard would be useful; for
various reasons there is no such a thing. Providing some bits
of it is IMO even more useless than providing 'signal'.
> > Note that thread cancellation does not map directly to exception
> > handling.
[ discution of thread cancellation vs EH - sniped ]
> That is definitely a problem...
There was some discution about that in the french commitee.
The problem is non trivial but interresting. There is no
point in analysing it in the standard; the french commitee
discussed it in order to propose Posix bindings, and its
discution wasn't intended to influence the C++ standard.
To answer your question: this is the wrong standard, or
at least the wrong time (perhaps we'll have C++ threads
in 2008).
--
Valentin Bonnard mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/06/01 Raw View
Petter Urkedal wrote:
>
> What happens if an exception is thrown and not caught inside a
> signal hander? I could not find any answer in the Nov96-Draft.
> However, signals is a part of the C++ standard, as inherited
> from C.
>
> In my opinion, it is very important that the exception is
> rethrown in the code of the thread which received the signal.
> This makes it possible to cancel a thread from another thread,
> and assuring that all destructors in the cancelled tread is
> called.
>
> If execptions are not rethrown, we have the option to
>
> * insert some I_am_here() check-points all around the code, or
>
> * discard the C++ style of programming, making cleanup-
> handers, or
>
> * never cancel threads, or
>
> * do some magic I'm not aware of.
You have to understand that all real-world implementations of C++
exceptions assume that exceptions only happen at certain known points
(i.e., in a throw exception, or in a call to a function that doesn't
have an empty exception-specification). If a completely asynchronous
signal occurs, and is turned into a C++ exception, it may crash, because
there may be things (including the exception handling data structures
themselves) that at that moment might not be in a coherent state.
Therefore, you should use the first solution, although I'd call it
CheckForSignal(). The signal handler (which must be a C-like function)
can only portably communicate with CheckForSignal() through a global
volatile variable of type sig_atomic_t. If you need a separate
communication channel for every thread (so that you can send the same
cancel signal to any thread), then you are automatically in
system-dependent territory.
All that said, I have in fact done what I just told you not to do, in a
Win32 system. I installed a hardware protection violation handler, and
made it throw an exception. This isn't guaranteed to work, for the
reasons outlined above, but it was in a system where it was preferable
to try to keep running and risk crashing, rather than simply aborting
unconditionally. And in lots of cases it worked fine. The exception was
an error message that contained the code address of the protection
fault, which was useful feedback to me, yet the fact that the system
usually kept running kept my customers happy.
--
Ciao,
Paul
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Tom Payne <thp@cs.ucr.edu>
Date: 1998/06/02 Raw View
In comp.std.c++ Valentin Bonnard <bonnardv@pratique.fr> wrote:
: Petter Urkedal <petter@matfys.lth.se> writes:
: > Christian Millour wrote:
: > >
: > > AFAIK, FDIS C++ is unaware of threads, and posix threads are unaware
: > > of C++. So there is no portable way. Different compiler vendors have
: > > different (typically per platform/os) solutions.
: >
: > But C++ is aware of signals.
: Not really. There is nothing you can do in a signal handler
: (I mean nothing useful).
: I don't even understand why signal is there in the standard.
C++ inherited its notion of signals from C, where signal handlers can
only perform a longjmp and/or set a flag of type volatile sigatomic_t.
Given that the standards, therefore, support only polled response to
asynchronous events, the answer to the original query is that the
polling code must throw the C++ exception that would have been thrown
by the handler.
There was a tedious (and somewhat contentious) thread on this matter
about a year and a half ago. It included some suggestions about how
range-table techniques might be used to efficiently implement real
asynchronous exceptions.
Tom Payne
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]