Create zombie process
Asked Answered
L

2

26

I am interested in creating a zombie process. To my understanding, zombie process happens when the parent process exits before the children process. However, I tried to recreate the zombie process using the following code:

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
{
  pid_t child_pid;

  child_pid = fork ();
  if (child_pid > 0) {
    exit(0);
  }
  else {
    sleep(100);
    exit (0);
  }
  return 0;
}

However, this code exits right after execute which is expected. However, as I do

ps aux | grep a.out

I found a.out is just running as a normal process, rather than a zombie process as I expected.

The OS I am using is ubuntu 14.04 64 bit

Liturgist answered 7/8, 2014 at 0:28 Comment(1)
Your code in the question does not create a zombie process because in your code, the parent process exits first while the child keeps running. (Remember fork() returns 0 in the child process and PID of the child in the parent process.) To see a zombie process, you need to make the child exit while the parent is still alive but hasn't waited on the child. If you just change line 10 of your code from if (child_pid > 0) to if (child_pid == 0), it will "fix" your code and you'll be able to see a zombie process when the child process exits.Northwester
F
36

Quoting:

To my understanding, zombie process happens when the parent process exits before the children process.

This is wrong. According to man 2 wait (see NOTES) :

A child that terminates, but has not been waited for becomes a "zombie".

So, if you want to create a zombie process, after the fork(2), the child-process should exit(), and the parent-process should sleep() before exiting, giving you time to observe the output of ps(1).

For instance, you can use the code below instead of yours, and use ps(1) while sleep()ing:

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

int main(void)
{
    pid_t pid;
    int status;

    if ((pid = fork()) < 0) {
        perror("fork");
        exit(1);
    }

    /* Child */
    if (pid == 0)
        exit(0);

    /* Parent
     * Gives you time to observe the zombie using ps(1) ... */
    sleep(100);

    /* ... and after that, parent wait(2)s its child's
     * exit status, and prints a relevant message. */
    pid = wait(&status);
    if (WIFEXITED(status))
        fprintf(stderr, "\n\t[%d]\tProcess %d exited with status %d.\n",
                (int) getpid(), pid, WEXITSTATUS(status));

    return 0;
}
Falster answered 10/8, 2014 at 12:25 Comment(3)
Thank you so much chrk! I tried your code, and I saw some zombie processes. But I still have one more concern. Why my code does not create a zombie process? According to the definition in your post, does the child process exited without being waited for by the parent (The parent had been exited without wait command). @FalsterLiturgist
@Liturgist Your code in the question does not create a zombie process because in your code, the parent process exits first while the child keeps running. (Remember fork() returns 0 in the child process and PID of the child in the parent process.) To see a zombie process, you need to make the child exit while the parent is still alive but hasn't waited on the child. If you just change line 10 of your code from if (child_pid > 0) to if (child_pid == 0), it will "fix" your code and you'll be able to see a zombie process when the child process exits.Northwester
Just to elaborate a bit more. If the parent exits first, what happens is that the child is now an orphan (its parent died) and the init process will adopt it (so the new parent is pid 1). The init process has a special handler registered to be notified when a children dies, so when the child dies it will wait for it to read its status code and therefore the child process does not become a zombie. If the init process were not to do that (common when running inside docker for example), you'd still have a zombie with your version.Foredoom
C
6

A zombie or a "defunct process" in Linux is a process that has been completed, but its entry still remains in the process table due to lack of correspondence between the parent and child processes. Usually, a parent process keeps a check on the status of its child processes through the wait() function. When the child process has finished, the wait function signals the parent to completely exit the process from the memory. However, if the parent fails to call the wait function for any of its children, the child process remains alive in the system as a dead or zombie process. These zombie processes might accumulate, in large numbers, on your system and affect its performance.

Below is a c program to creating a Zombie-Process on our system Save this file as zombie.c:

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
{
  pid_t child_pid;

  child_pid = fork ();
  if (child_pid > 0) {
    sleep (60);
  }
  else {
    exit (0);
  }
  return 0;
}

The zombie process created through this code will run for 60 seconds. You can increase the time duration by specifying a time(in seconds) in the sleep() function.

Compile this program

gcc zombie.c

Now run the zombie program:

./a.out

The ps command will now also show this defunct process, open a new terminal and use the below command to check the defunct process:

aamir@aamir:~/process$ ps -ef | grep a.out
aamir    10171  3052  0 17:12 pts/0    00:00:00 ./a.out
aamir    10172 10171  0 17:12 pts/0    00:00:00 [a.out] <defunct> #Zombie process
aamir    10177  3096  0 17:12 pts/2    00:00:00 grep --color=auto a.out
Captain answered 20/12, 2020 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.