1

So when a child dies parent gets SIGCHLD but if parent dies before doing wait(), the child is reparented to init. At this point in time the child is a zombie i.e. <defunct>.

What happens next?

Does init do wait() on that child? if yes, when does it do it? Any guarantees regarding time-limit?

hari
  • 9,439
  • 27
  • 76
  • 110
  • Not sure about your wording, but to clarify, the child is a zombie for time between its death and the time its parent (either the original parent, or init ) waits on it. The wording of your question implies the child only becomes a zombie after the parent dies. – William Pursell Dec 13 '11 at 23:54

1 Answers1

2

Yes, init will immediately reap all children. If you make a process which ignores SIGCHLD and accumulates many zombies you can get rid of them by killing that parent via the mechanism you describe.

For reference here is the main loop of init while in multi user mode. requested_transition is set by signalling init (e.g. the classic kill -1 1 to read an updated inittab):

    while (!requested_transition)
            if ((pid = waitpid(-1, (int *) 0, 0)) != -1)
                    collect_child(pid);

(collect_child handles cases where init has some special interest in the process, such as a login shell which now needs a new getty)

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
  • Thanks for the answer Ben. If `init` is going to reap immediately, does it make no sense to define an explicit handler for SIGCHLD to do wait()? I experienced that having such a handler is very useful. It does "reap"ing much quicker than `init`. Do you agree? – hari Dec 14 '11 at 00:35
  • 1
    If your process is *still alive* it is up to you to reap. Leaving zombies around until your process exits is bad. If it's an unlimited number you can run yourself out of procs. – Ben Jackson Dec 14 '11 at 01:47
  • Thanks Ben. BTW, I am not following the code snippet you provided. It looks intriguing though :) Can you please elaborate on that? I am looking at freebsd source and not finding such code block. – hari Dec 14 '11 at 07:03
  • 1
    That's from `/usr/src/sbin/init/init.c` and it's a loop of `waitpid()` (fancier `wait()`) until a signal handler asynchronously sets `requested_transition`. When the kernel reparents a process to `init` it wakes up in that loop. The zombie goes away after the wait: The purpose of the zombie is to retain the state that `waitpid()` can receive. – Ben Jackson Dec 14 '11 at 09:02