Topic: Throwing an exception from within a signal handler


Author: Dick Menninger <Dick.Menninger@daytonoh.attgis.com>
Date: 1996/02/08
Raw View
> ==========Tom Payne, 2/4/96==========

[...]

> Atomicity of such updates to atomic variables is not always a problem.
> For instance, in most cases a signal handler can increment an atomic
> counter (e.g. a timer) without difficulties, even though the
> read/modify/write sequence is not atomic.  In the case of nonatomic
> variables, atomicity must be enforced by blocking certain signals.
> Such blockage could be portably implemented via atomic blockage flags,
> which, in turn, are volatile atomic variables that must be read by
> signal handers.

Although that could keep them from reading a bad value,
they have no way to wait for it to become valid if they
interrupted the owner. So, the updater thread would have
to fully block the signals that really need the value in the
handler for handling to proceed.  That is, the problems
are more severe than between threads that do not interrupt
each other (a signal handler is just a specialized thread,
whether or not the environment's terminology calls it that
is irrelevant).

Good Day
Dick
Dick.Menninger@DaytonOH.ATTGIS.COM
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy is
  in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]





Author: thp@cs.ucr.edu (Tom Payne)
Date: 1996/02/09
Raw View
Dick Menninger (Dick.Menninger@daytonoh.attgis.com) wrote:
: > ==========Tom Payne, 2/4/96==========
:
: [...]
:
: > Atomicity of such updates to atomic variables is not always a problem.
: > For instance, in most cases a signal handler can increment an atomic
: > counter (e.g. a timer) without difficulties, even though the
: > read/modify/write sequence is not atomic.  In the case of nonatomic
: > variables, atomicity must be enforced by blocking certain signals.
: > Such blockage could be portably implemented via atomic blockage flags,
: > which, in turn, are volatile atomic variables that must be read by
: > signal handers.
:
: Although that could keep them from reading a bad value,
: they have no way to wait for it to become valid if they
: interrupted the owner. So, the updater thread would have
: to fully block the signals that really need the value in the
: handler for handling to proceed.  That is, the problems
: are more severe than between threads that do not interrupt
: each other (a signal handler is just a specialized thread,
: whether or not the environment's terminology calls it that
: is irrelevant).

Agreed: the need to block concurrent access to shared data is often
inevitable.  To lock out standard threads during such a critical
section, one acquires a lock.  To lock out signal-sustained
pseudothreads, one blocks the corresponding signals.  It is a defining
characteristic of threads, however, that they can wait.

Tom Payne

[Moderator's note: this is a valuable discussion, but it's beginning to
drift away from C++ standardization.  I suggest continuing it in
comp.compilers.  mha]

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy is
  in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]





Author: thp@cs.ucr.edu (Tom Payne)
Date: 1996/01/27
Raw View
J. Kanze (kanze@gabi.gabi-soft.fr) wrote:
: In article <DLCosx.Hn1@falcon.daytonoh.attgis.com> Dick Menninger
: <Dick.Menninger@daytonoh.attgis.com> writes:
:
: > > ==========Steve Clamage, 1/16/96==========
: > > In C, a signal handler isn't allowed to do much of anything, precisely
: > > because the program state can't be known and may be inconsistent. The
: > > same is true in C++.
:
: > It is just like an interrupt handler in that it could
: > deadlock with the code it preempts.  OSes deal with
: > that and do quite meaty stuff in the interrupt handlers.
[...]
:
: From ISO 9899, section 7.7.1.1: ``If the signal occurs other than as the
: 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 of the signal
: number corresponding to the signal tha 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.''
[...]

In other words, the only asynchronous activity allowed to programs
with defined behavior is polling volatile atomic variables that are
set by signal handlers.  Thus far, no one has given me a reason for
prohibiting signal handlers from reading volatile atomic variables,
which is a common practice in interrupt handlers (even those written
in C/C++).

Tom Payne (thp@cs.ucr.edu)
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: thp@cs.ucr.edu (Tom Payne)
Date: 1996/01/27
Raw View
Bill Leonard (bill@amber.ssd.hcsc.com) wrote:
: In article <4e35jg$k8c@galaxy.ucr.edu>, thp@cs.ucr.edu (Tom Payne) writes:
: > If the ABI implementation of signal blocking is missing or has high
: > overhead, then we can use global flags inside the program to reduce
: > blocking to setting a bit and reduce unblocking to clearing that bit
: > and checking whether a deferred signal has arrived (in which case
: > there is additional overhead to check which signal to process it).
:
: Maybe I've missed something here, but wouldn't that code have to appear in
: every function prologue and epilogue?  The only reason for signal blocking
: (I thought) was that trying to propagate an exception into or through a
: stack frame that is partially constructed or destroyed is problematic.
:
: I certainly wouldn't want code to check (and handle) a signal to be
: generated in every function prologue!  Talk about code bloat!

We need to shrink-wrap critical sections where the stack might be in
an inconsistent state (prologues and epilogues) against exceptions
thrown by signal handlers.  We can do this by:

  1. setting a flag during such regions,

  2. having the compiler generate PC-range tables telling where
     these sections are,

  3. using some kind of pattern recognition to determine whether
     the interrupted function invocation was in a critical section.

Solution #1 involves at each critical section two writes and a
conditional jump around a call to a function that throws deferred
exceptions (as a proxy for the signal handler).  Solutions #2 and #3,
proposed by David Chase, involve no overhead in time, but #2 involves
some space overhead.

Steve Clamage has raised the question of existing libraries.  Under
solutions #1 and #2, such libraries would have to be recompiled or
else calls to them would have to be shrink-wrapped for the duration of
the called function (leading to objectionable latencies if the
shrink-wrapping blocks ALL signals).  Solution #3 would eliminate the
need for recompilation, but you and Steve have expressed doubt about
the feasibility of being able to programmatically detect these
critical regions.


Tom Payne (thp@cs.ucr.edu)
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
Date: 1996/01/24
Raw View
G. Bowden Wise writes:

|> J. Kanze wrote:

|> > I use reference counted pointers a lot, but they have their own set of
|> > problems.  I can very well understand the committees reluctance to
|> > adapt them.

|> Can you share with us the problems with reference counter pointers?
|> How do those problems compare with the auto_ptr problems?  Perhaps
|> we need some kind of hybrid between the two.

The problems are not so much with use, but with how to standardize.

There are two distinct approaches with regards to reference counted
pointers: invasive and non-invasive.

Invasive reference counting involves significant constraints with
regards to the counted objects.  None of the basic types meet these
constraints, nor can they be made to.  None of the other types in the
library meet them, either.  In this case, the committee could eventual
change this, but in many cases (iterators, for example), meeting the
constraints would involve significant overhead, which would then be
paid by everyone, including those who didn't use reference counting.
(For a good discussion of invasive reference counting, see Scott
Meyers' new book.)

Non-invasive reference counting has significant run time overhead.  In
fact, the overhead is enough to make invasive reference counting the
prefered method in most cases (IMHO).  (For an example of non-invasive
reference counting, see Barton and Nackman.)  My experience suggests
that in most cases where reference counting is appropriate, I am
implementing reference semantics for polymorphic objects.  In these
cases, the invasive approach is definitly to be prefered.  I suspect
that if the standard had adapted a non-invasive approach, I probably
would not have used it anyway.  (My own reference counted pointers
require the referenced object to inherit from GB_RefCntObj.)

Another potential problem: reference counted pointers do not work when
there are cycles in the reference chain.  As such, there actual field
of use is much more restricted than one would like (for something in
the standard); I use them because most of my objects fall into
hierarchial structures, which forbid cycles.  But for many application
domains, the restriction that the references not contain cycles is
non-trivial.  I can imagine that some people would oppose their
presence in the standard on the grounds that we do not want to
standardize something that is so intrinsically dangerous; it might
give people a false sense of security.  (By the same logic, of course,
we should eliminate gets, and even sprintf, from the standard.
History rules, however.)

In view of these two problems, I myself do not see a real role for
reference counted pointers in the standard.  Note that neither of
these problems affect auto_ptr.  (In theory, I guess, you could create
a cycle with auto_ptr, but I cannot really imagine the case occuring
in real code.)

--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, itudes et rialisations en logiciel orienti objet --
                -- A la recherche d'une activiti dans une region francophone
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: bill@amber.ssd.hcsc.com (Bill Leonard)
Date: 1996/01/24
Raw View
In article <4e35jg$k8c@galaxy.ucr.edu>, thp@cs.ucr.edu (Tom Payne) writes:
> If the ABI implementation of signal blocking is missing or has high
> overhead, then we can use global flags inside the program to reduce
> blocking to setting a bit and reduce unblocking to clearing that bit
> and checking whether a deferred signal has arrived (in which case
> there is additional overhead to check which signal to process it).

Maybe I've missed something here, but wouldn't that code have to appear in
every function prologue and epilogue?  The only reason for signal blocking
(I thought) was that trying to propagate an exception into or through a
stack frame that is partially constructed or destroyed is problematic.

I certainly wouldn't want code to check (and handle) a signal to be
generated in every function prologue!  Talk about code bloat!

> Agreed!!  Note however that an increasing percentage of programs have
> asynchornous aspects to them, under headings such as "event-driven",
> "real-time", "multi-threaded", "parallel", "concurrent", etc.

Many of those programs also have pretty stringent performance requirements.
Our business *is* real-time, and I've seen many times when getting rid of
just one instruction in a key location would buy a lot of performance.  I'd
be against any requirement that forced me to add instructions in function
prologues/epilogues.

--
Bill Leonard
Harris Computer Systems Corporation
2101 W. Cypress Creek Road
Fort Lauderdale, FL  33309
Bill.Leonard@mail.hcsc.com

These opinions and statements are my own and do not necessarily reflect the
opinions or positions of Harris Computer Systems Corporation.

------------------------------------------------------------------------------
There's something wrong with an industry in which amazement is a common
reaction to things going right.

"Hard work never scared me.  Oh, sure, it has startled me from a distance."
                                                       -- Professor Fishhawk
------------------------------------------------------------------------------
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: shankar@engr.sgi.com (Shankar Unni)
Date: 1996/01/10
Raw View
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:

> Because the draft standard doesn't say anything about it,
> I guess it is implicitly undefined behaviour.

> >Again, I wonder why this passed the moderation ...

Because signals are a part of ANSI C, and we really need to address at
least all ANSI C issues as part of any C++ standard?

 [Yes. -Moderator (fjh).]

--
Shankar Unni    E-Mail: shankar@sgi.com
Silicon Graphics Inc.   Phone: +1-415-933-2072
URL: http://reality.sgi.com/employees/shankar
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: thp@cs.ucr.edu (Tom Payne)
Date: 1996/01/16
Raw View
Fergus Henderson (fjh@munta.cs.mu.OZ.AU) wrote:
:
: >In article <4cpmh0$ltf@natasha.rmii.com>, jtc@rmii.com (Jim Cochrane) wrote:

: >>>
: >>> Does the proposed ANSI standard say anything about throwing an exception
: >>> from within a signal handler?
:
: No.
:
: >>> Is the resulting behavior safe and
: >>> well-defined, or is it undefined or implementation-dependent?
:
: Because the draft standard doesn't say anything about it,
: I guess it is implicitly undefined behaviour.
:
[...]
:
: I think the issue of whether the standard says anything about *Foo* is
: generally appropriate to comp.std.c++, even if the answer is "No.", and
: the resulting discussion rather short.

Implicit in a qestion of what the Standard says are the related
questions of what it should say and why --- why shouldn't signal
handlers be allowed to throw exceptions?  (The question seems both
interesting and appropriate.)

Tom Payne (thp@cs.ucr.edu)
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
Date: 1996/01/16
Raw View
In article <4dekiv$22h@galaxy.ucr.edu> thp@cs.ucr.edu (Tom Payne)
writes:

|> Implicit in a qestion of what the Standard says are the related
|> questions of what it should say and why --- why shouldn't signal
|> handlers be allowed to throw exceptions?  (The question seems both
|> interesting and appropriate.)

Because of the problems related to atomicity which crop up when
asynchronous events are considered.



Author: jtc@rmii.com (Jim Cochrane)
Date: 1996/01/08
Raw View
Does the proposed ANSI standard say anything about throwing an exception
from within a signal handler?  Is the resulting behavior safe and well-defined,
or is it undefined or implementation-dependent?

Thanks,
Jim Cochrane
jcochran@costello.den.csci.csc.com






Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/01/09
Raw View
Etay_Bogner@mail.stil.scitex.com (Etay Bogner) writes:

>In article <4cpmh0$ltf@natasha.rmii.com>, jtc@rmii.com (Jim Cochrane) wrote:
>
>>> Does the proposed ANSI standard say anything about throwing an exception
>>> from within a signal handler?

No.

>>> Is the resulting behavior safe and
>>> well-defined, or is it undefined or implementation-dependent?

Because the draft standard doesn't say anything about it,
I guess it is implicitly undefined behaviour.

>Again, I wonder why this passed the moderation ...
>
>signal handlers is a C++ issue ? come on ...

I think the issue of whether the standard says anything about *Foo* is
generally appropriate to comp.std.c++, even if the answer is "No.", and
the resulting discussion rather short.

P.S. Probably Etay Bogner's meta-post should not have got past moderation ;-)
As a reminder, comments on the moderation policy should be addressed
c++-std-request@ncar.ucar.edu.

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3






Author: Etay_Bogner@mail.stil.scitex.com (Etay Bogner)
Date: 1996/01/09
Raw View
In article <4cpmh0$ltf@natasha.rmii.com>, jtc@rmii.com (Jim Cochrane) wrote:

>> Does the proposed ANSI standard say anything about throwing an exception
>> from within a signal handler?  Is the resulting behavior safe and
well-defined,
>> or is it undefined or implementation-dependent?
>>

Again, I wonder why this passed the moderation ...

signal handlers is a C++ issue ? come on ...

--
-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]