Understanding and Managing Zombie Processes in Linux — With Working Example!

Someshwaran M
5 min readAug 5, 2024

--

Title image of the Zombie Processes Article
Zombie Processes (source: https://www.theurbanpenguin.com)

In Linux, a Zombie Process is a process that has completed execution but still has an entry in the process table. This article explains zombie processes in simple terms and provides a step-by-step guide to simulate and manage a zombie process using a Docker container.

# Let’s start with “What is a Zombie Process?”

Low-Level design of a Life Cycle of a process
Low-Level Life Cycle of a process (source: Linux Performance and Tuning Guidelines book from IBM Red books)

> To understand Zombie, let’s try to understand the Basic Lifecycle of a Process 👇

1. Execution: A process executes its tasks.

2. Termination: After completing its tasks, the process terminates.

3. Zombie State: The process moves into a zombie state if its parent process hasn’t yet read its exit status.

4. Reaping/Collecting: The parent process collects the exit status using system calls like wait(), and the zombie process entry is removed from the process table.

— — — — — — — — — — — — OPTIONAL — — — — — — — — — — — — — —

To those to hear the word process table for the first time, let me take a quick detour of what is a Process Table:

The process table is a table or a record used by the operating system to keep track of all active processes. Each entry contains essential information about a process, such as its unique Process ID (PID), state, memory usage, and more. It helps manage and schedule processes, allocate resources, and facilitate communication between them. Without this record or table, it is impossible to manage the thousands of processes.

In simple words, if you are a Microsoft Windows users, it is the programs that you see in Task Manager GUI.

Task Manager Windows Image with Processes, CPU, Memory, Disk and Network Usage
Task Manager Windows (source: https://www.howtogeek.com/405806/windows-task-manager-the-complete-guide/)

For Linux users, you can find the process table using ps or top commands:

The process table image from the linux operating system with the processes, pid, memory, and cpu usage.
Process Table in Linux(Ubuntu) using top command

Useful Resources on Processes: Geeksforgeeks

— — — — — — — — — — — — OPTIONAL — — — — — — — — — — — — — —

> Why Do Zombie Processes Occur?

When a child process terminates, but its parent process does not call wait() to collect the exit() status. This leaves an entry in the process table until the parent process acknowledges the information from the terminated child process.

> Resource Impact

While zombie processes do not consume CPU or memory resources, they occupy a slot in the process table. If too many zombies accumulate, it can prevent the creation of new processes.

If you have a question 🤔 of “What is the total size of the process table or how many maximum processes I could simultaneously run?”

As a Linux users, try running:

# Linux
$ cat /proc/sys/kernel/pid_max
$ 99999

# Note, 99999 is the number of pid_max, but remember, each process utilizes
# a part of the memory so it will be challenging to occupy the
# complete process table.

For Windows, please feel free to use the “Windows Subsystem for Linux(WSL)”

# Simulating and Managing a Zombie Process

* Step 1: Create a Docker Container

(Assuming, you already installed Docker Desktop and its dependencies)

Start by creating a Docker container with an Ubuntu image:

docker run -it - name zombie-demo ubuntu

* Step 2: Write a Program to Generate a Zombie Process

Inside the Docker container, create a C program to demonstrate a zombie process. Save the following code as zombie.c:


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

int main() {
pid_t pid = fork();

if (pid < 0) {
// Fork failed
perror("fork");
exit(EXIT_FAILURE);
}

if (pid == 0) {
// Child process
printf("Child process (PID: %d) exiting...\n", getpid());
exit(EXIT_SUCCESS); // Exit, but parent won't clean up
} else {
// Parent process
printf("Parent process (PID: %d) sleeping...\n", getpid());
sleep(60); // Sleep for a while to allow checking zombie status
printf("Parent process waking up...\n");
}

return 0;
}

* Step 3: Compile and Run the Program

Install gcc (refer, what is GNU Compiler Collection) if it’s not already available and compile the program:

apt-get update
apt-get install -y gcc
gcc -o zombie zombie.c ## Compiling the C program
./zombie ## To run the compiled program

Output

An example of the output after executing the Zombie C program.
Output you get, post executing the Zombie program

After 60 seconds i.e. once the parent process completes the sleep cycle, you’ll get this Output:

An example of the complete output observed once the parent process wakes up, post completing the 60 seconds sleep.
The complete output observed once the parent process wakes up

* Step 4: Check for Zombie Processes

In another terminal, check the process list to identify the zombie process:

ps aux | grep 'Z'

You should see an entry with a status of Z (for zombie), such as:

The complete processs table including the Parent Process and the Zombie Process.
The complete Process Table using “ps -aux” command
Using “grep” to filter the Zombie process from the process table.
Using “grep” to filter the Zombie process
Using an alternative to “ps -aux” i.e. “top” command to get more visualized structure of the linux processes
Using an alternative to “ps -aux” i.e. “top” command to get more visualized structure of processes

From the above top command, you could clearly notice that the Zombie is updated to 1 and you can notice the character Z against a Zombie command.

* Step 5: Manage Zombie Processes

After the parent process completes its sleep, it should automatically clean up the zombie process. You can manually kill the zombie process by sending a signal to the parent process:

kill -s SIGCHLD <enter_the_parent_pid>

To Find the parent process ID (PID) with:

ps aux | grep 'zombie'

Or, just use top as mentioned above

> Conclusion

Zombie processes are those that have finished execution but remain in the process table because their parent hasn’t collected their exit() status. By using Docker and a simple C program, you can simulate and manage zombie processes to understand their behavior and how to handle them effectively.

> Additional Resources

  • You can check this WikiPedia page on Zombie Processes, it is interesting with a code snippet.
  • Useful Resources on Processes: Geeksforgeeks

--

--

Someshwaran M
Someshwaran M

Written by Someshwaran M

I am an Open-Source Enthusiast. I learned a lot from the Open-Source community and I love how collaboration, knowledge sharing happens through Open-Source!