lkml.org 
[lkml]   [1996]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: On SIGCHLD signal semantics
On Fri, 14 Jun 1996, Theodore Y. Ts'o wrote:

> Why are we trying to work so hard to accomodate broken programs? Broken
> programs should be fixed, not coddled by adding needless complexity into
> the kernel.

I'll recap to clear up the misunderstanding that definitely exists here.
Throughout this, I'll assume no signals other than SIGCHLD are involved.
I'm not proposing behavioural changes when this assumption is broken
(SIGSTOP'ped children, etc), so making this assumption will reduce
confusion. I'll also assume a parent process has remaining children
(zombies or not), otherwise a wait syscall always fails with ECHILD.

Currently, Linux's SIGCHLD signal semantics are

(a) When the parent has set or inherited a SIGCHLD signal handler other
than SIG_IGN:
- A wait syscall will suspend the parent, if necessary, until one of
its children exits (i.e. becomes a zombie). The first zombie found
is then cleaned out and its pid is returned to the parent.
- The kernel does not clean out any other of the parent's zombies.

(b) When the parent has explicitly set its SIGCHLD signal handler to
SIG_IGN:
- A wait syscall will suspend the parent until one of its children
exits. When the parent is woken up, the resulting zombie is cleaned
out and its pid is returned to the parent.
- The kernel cleans out any zombies the parent leaves behind.

(c) When the parent has inherited a SIGCHLD signal handler of SIG_IGN:
Same as (b).

There are a few problems with this.

First, applications that set their SIGCHLD handler to SIG_IGN are not
inherently broken. They are simply expecting System V semantics. But
they are only getting a partial implementation of these semantics. Worse,
a wait syscall will return a different result depending on whether or not
a child exits before the parent issues the syscall.

To fix this, new definitions are needed. A dead zombie is a process that
exits while its parent's SIGCHLD signal handler is SIG_IGN. A live zombie
is a process that exits while its parent's SIGCHLD signal handler is *not*
SIG_IGN. Now, the above (b) can be replaced with

(b) When the parent has explicitly set its SIGCHLD signal handler to
SIG_IGN:
- A wait syscall will clean out any remaining dead zombies (this is
just an optimization). The syscall will then do one of two things.
If any live zombies remain, the syscall will clean out the first one
it finds and return its pid to the parent. Otherwise, the parent
will be suspended, if necessary, until *all* its remaining children
exit. As each child exits, the resulting dead zombie is cleaned out.
When no children remain, the syscall will fail with ECHILD.
- The kernel cleans out any dead zombies the parent leaves behind.

This change to (b) results in System V semantics. Better yet, an
application must explicitly request wait's broken behaviour by spawning
children *before* setting its SIGCHLD signal handler to SIG_IGN.

Now, on to the second problem...

Applications that do a wait syscall with an inherited SIGCHLD signal
handler are not inherently broken. They are simply expecting BSD
semantics. But they also are only getting a partial implementation. If
they are unlucky enough to inherit SIG_IGN as their SIGCHLD signal
handler, they will randomly fail. Indeed, the only difference the above
change to (b) introduces to this scenario is to make this failure certain.
The problem here is one of error localization and of process independence.
Here, the kernel is penalizing the wrong programme, letting the real
culprit (which could be a few fork()'s away up the process tree) continue
scot-free.

The solution to this second problem involves slightly redefining live and
dead zombies. A dead zombie is a process that exits while its parent's
SIGCHLD handler is *explicitly* set to SIG_IGN. A live zombie is any
other zombie. Now, (b) reads the same as the above System V replacement
for it (keeping the new definitions in mind) and (c) becomes

(c) When the parent has inherited a SIGCHLD signal handler of SIG_IGN:
Same as (a), instead of (b).

This gives POSIX compliance in all three (a), (b) and (c), BSD
compatibility in cases (a) and (c), System V compatibility in cases (a)
and (b). BSD compatibility in case (b) is a non-issue because in BSD
SIGCHLD signal semantics, SIG_IGN is the same as SIG_DFL, and therefore
there is no real reason for a BSD programme to explicitly set its SIGCHLD
signal handler to SIG_IGN. System V compatibility in case (c) depends on
whether or not one accepts my previously derived contention that the
X/Open specification leaves case (c) as unspecified. If this contention
doesn't hold water, one must still decide between the X/Open spec and an
implementation that runs BSD applications properly, in addition to System
V applications. In my view, the spec loses, hands down.

Note that none of the above affects other aspects of having SIG_IGN as a
SIGCHLD signal handler (signal() return values, etc.). As to the
perceived complexity of the above, one need only document that a programme
gets BSD semantics until it sets its SIGCHLD handler, at which point it
will have to deal with System V semantics.

One open question remains, and that is the advisability of causing child
processes to inherit SIG_IGN as their SIGCHLD signal handler (i.e. to do
an exec* syscall while ignoring child processes). Although above I
characterize programmes that implement such behaviour as "culprits", I do
not, at this time, know if they are in the wrong. I have yet to see a
compelling case for or against this practice. I therefore leave it alone
(for now).

Your witness, Counsellor...

Marc.

+----------------------------------+-----------------------------------+
| Marc Aurele La France | work: 1-403-492-9310 |
| Computing and Network Services | fax: 1-403-492-1729 |
| 352 General Services Building | email: tsi@ualberta.ca |
| University of Alberta +-----------------------------------+
| Edmonton, Alberta | |
| T6G 2H1 | Standard disclaimers apply |
| CANADA | |
+----------------------------------+-----------------------------------+



\
 
 \ /
  Last update: 2005-03-22 13:37    [W:0.735 / U:0.052 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site