Re: Bug in signalmodule.c + FIX (probably a hack :-)

Guido.van.Rossum@cwi.nl
Thu, 08 Sep 1994 14:51:53 +0200

Michael Scharf writes:

> I got a problem with the signal module on IRIX5. I created the
> server below (which is based on the example in the python
> manual). When the parent gets the signal SIGCLD then the signal
> module enters an infinite recursion...

> I fixed it, but I did it blindly - I mean without understanding
> what's going on. But this fix seems to solve the problem - at least
> for me :-)

Aha, I see the problem. This is because on System V, SIGCHLD (for
which SIGCLD is just an alias) has very special semantics: it is
raised whenever there's at least one waiting child and the signal is
enabled. The Python signal module delays handling of all signals
until the interpreter is ready for them by setting a flag and then
re-instating the signal handler. This is a change compared to the
System V C semantics: there, a signal's handler is reset to SIG_DFL
and must explicitly re-caught by a call to signal(). The Python
signal module attempts to mimic the BSD signal semantics where a
signal setting remains in effect until explicitly reset.

Unfortunately all this causes a recursion loop for SIGCHLD: when the
handler (in C) sets the flag and re-instates the signal handler, the
child has not yet been waited for so the signal is raised again
immediately, causing recursion. Michael's fix stops recursive calls
to the signal handler, but this means that the signal will not be
handled again, until the Python code calls signal() again.

I'm not sure what the best fix for this situation is.

We can't call the Python handler from within the C handler for a
variety of reasons (e.g. the Python interpreter could be in the middle
of updating a mutable object).

Changing to System V semantics (requiring the Python handler to
re-instate the handler) for all signals has the problem that there is
a window within which signals may be lost (between the moment the C
handler returns and the Python handler re-instates the handler). (I
assume that in System V, when a non-SIGCHLD signal occurs while the
handler for it is still executing, the signal's delivery is delayed,
so there is no window for C applications.)

Waiting for the child in the C handler would require a complicated
manoeuver to pass its exit status to Python.

Maybe the best solution would be to make an exception for SIGCHLD, and
use System V semantics (handlers must explicitly re-instate
themselves) for this signal but BSD semantics (handlers remain in
effect until explicitly reset) for all other signals.

Question: would this solution break on BSD systems?

--Guido van Rossum, CWI, Amsterdam <Guido.van.Rossum@cwi.nl>
<URL:http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>