Re: fork() race in SIGCHLD handler

From: Kasper Dupont (kasperd_at_daimi.au.dk)
Date: 12/30/03


Date: Tue, 30 Dec 2003 21:24:44 +0100


"P.T. Breuer" wrote:
>
> Well, this sounds a bit like the old issue of "who runs first".

No matter who executes first you should get correct behaviour.
Even if you know who executes first, you don't know how many
cycles it will get. Eventually you will have a situation where
the first executing process gets preempted before it returned
from the fork function. It is often desirable to have the child
run first for performance reasons, since we are talking about
performance it doesn't hurt too much if we in a few rare cases
have the parent execute first.

printf("%d",fork()==fork()==fork()); /* :-) */

>
> > address space. The parent process after fork()ing is beginning after the
> > child process has already terminated.
>
> Uh huh. Very likely. So? Isn't that allowed? There's nothing wrong with
> that.

Not just likely, also desirable. I think you will have the
smallest number of context switches that way.

>
> > At first I thought this may be a kernel or glibc bug, but on reflection I am
> > not so sure - I do not think the asynchronous SIGCHLD handler in the parent
> > process is required to wait around for the process in which it is executing
> > to begin executing synchronously after fork()ing.
>
> Well, in fact the handler executes (because the child dies)
> before the return value from the fork is known!

Well, there is a race between the process executing and the
signal handler. You cannot use a lock to protect against a
singal handler, as that will cause a deadlock. So I guess
the only solution is to mask the handler while the process
is in the critical region. And it seems the fork() call and
the assignment to the variable need both be in the critical
region. So masking before fork and unmasking after assigning
to the variable probably is the best (only?) solution.

>
> It sounds like you should delay setting the handler in the parent till
> the fork has returned, but that leaves a window in which the child can
> die unattended.

You need the handler to be ready before the signal can
arrive. That means the handler must be set up before the
fork call which is responsible for the signal eventually
arriving in the parent process. I don't know what will
happen if you get the signal while it is blocked and first
then actually installs the handler. I would avoid that by
installing the handler before fork and just keep the signal
blocked during the critical region in the parent.

>
> > pid_t child_pid = -1;
>
> It makes me nervous not having this static.

Shouldn't make any difference.

> Shrug. SHouldn't you declare this volatile too?

Might be a good idea. But is that really necesarry if it
is protected with a mutual exclusion implemented by
blocking the signal?

-- 
Kasper Dupont -- der bruger for meget tid paa usenet.
For sending spam use mailto:aaarep@daimi.au.dk
/* Would you like fries with that? */


Relevant Pages

  • Re: fork() race in SIGCHLD handler
    ... process to execute after fork twice in the 2.6.0 series. ... > not so sure - I do not think the asynchronous SIGCHLD handler in the parent ... > process is required to wait around for the process in which it is executing ... > difficulty by putting a flag in the first line of the parent process after ...
    (comp.os.linux.development.system)
  • Re: fork() race in SIGCHLD handler
    ... process to execute after fork twice in the 2.6.0 series. ... > not so sure - I do not think the asynchronous SIGCHLD handler in the parent ... > process is required to wait around for the process in which it is executing ... > difficulty by putting a flag in the first line of the parent process after ...
    (comp.unix.programmer)
  • Re: forking in c
    ... each child process should have a child process of their own. ... > meanwhile the parent process will have a childpid greater then 0 and it will ... Outside of failures in fork(), the parent /is/ creating new child processes ... continues executing from the first fork ...
    (comp.unix.programmer)
  • Re: fork() race in SIGCHLD handler
    ... from the fork function. ... The parent process after forking is beginning after the ... >> process is required to wait around for the process in which it is executing ... in fact the handler executes ...
    (comp.os.linux.development.system)
  • Re: Exception/error returns - values or raised conditions?
    ... They can be ignored by the process executing when they trigger so I ... handler to be changed by the dynamic execution of the program. ... The key being that each instruction would trap to the handler ... I've not seen types 2 and 3 provided by any language (by the operating ...
    (comp.lang.misc)