Can this C code create zombie processes?

8.2k views Asked by At

I am wondering if the following code can create zombies:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(){
    int i=1;
    pid_t p;
    p = fork();
    i++;
    if(p!=0){
        waitpid(p, NULL, 0);
    }
    printf("%d\n",i);
    return 0;
}

So, the parent process calls the waitpid for the child process, which returns immediately if the child has not already exited. So, no zombies can arise so far. But, if the child exits before

return 0;
command this would be a zombie then? I am actually confused about it. Should the waitpid be the last line of code before the program terminates? Any help would be appreciated. Thanks!

2

There are 2 answers

2
alk On BEST ANSWER

The child only becomes a zombie if it ends and the parent doesn't call wait*() as long as itself lives on.

In the moment the parent also ends the child is reaped by the init process which will take care to call wait*() on the child, so it will finally end and with this leave the zombie state and disappears from the process list.

To provoke the child created in your example code to become a zombie modify the code for example as follows:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void) 
{
    pid_t p = fork();

    if (p != 0) 
    {
        waitpid(p, NULL, 0); /* See if the child already had ended. */
        sleep(1); /* Wait 1 seconds for the child to end. And eat away the SIGCHLD in case if arrived. */
        pause(); /* Suspend main task. */
    }
    else
    {
        sleep(3); /* Just let the child live for some tme before becoming a zombie. */
    }

    return 0;
}

Due to the two following facts:

  • the child sleeps for 3s so the parent's call to waitpid() most probably will always fail
  • the default handling of SIGCHLD is to ignrore it.

the code above in fact is the same as:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void) 
{
    pid_t p = fork();

    if (p != 0) 
    {
        pause(); /* Suspend main task. */
    }
    else
    {
        sleep(3); /* Just let the child live for some tme before becoming a zombie. */
    }

    return 0;
}
0
aneesh joshi On

I found a simple way to create a zombie process and test it using ps -e

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

void  main()
{
    pid_t pid;
    pid = fork();
    //parent sleeps while the child has exited
    //not an orphan since parent still alive
    //child will be still present in process table
    if(pid==0)
    {//child
        exit(0);
    }
    else
    {//parent
        sleep(15);
    }
}

run ps -e while within the 15 seconds... you will see

6454 pts/2 00:00:00 a.out < defunct >