Zombie Processes in Linux What They Are and How to Prevent Them

Zombie Processes in Linux What They Are and How to Prevent Them

- 6 mins

What Is a Zombie Process in Linux?

Ever noticed a mysterious <defunct> process sitting quietly in your ps output? That’s a zombie process — a child process that has completed execution but still lingers in the process table.

In Linux, when a child process exits, it leaves behind an exit status that the parent process needs to collect. Until that status is read, the process isn’t completely removed from the process table. During that time, it’s considered a zombie.

Normally, the parent reaps the child’s exit status using wait() or waitpid(). If it fails to do so — either because it’s sleeping, buggy, or ignoring signals — the zombie sticks around.


Creating a Zombie Process (Code Example)

Let’s take a simple example to demonstrate this. We’ll fork a child process, let it terminate immediately, and then delay the parent:

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

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

    if (pid == 0) {
        // This is the child process
        printf("Child process (PID: %d) exiting...\n", getpid());
        exit(0);
    } else {
        // Parent goes to sleep
        printf("Parent sleeping... (PID: %d)\n", getpid());
        sleep(120);
    }

    return 0;
}

Execute c code and run:

gcc -o zombie zombie.c
./zombie

zombie


What Happens in This Program?


Verifying the Zombie

Once this code runs, we can use standard process tools to observe the zombie:

ps aux | grep Z

Or:

ps -eo pid,ppid,stat,cmd | grep defunct

Look for processes with status Z or the word <defunct> in the command column.

Or:

You can use top command to see zombie processes

zombie


Why Zombie Processes Matter

While a few zombie processes aren’t dangerous, a large number of them can fill the finite process table. When that happens:

That’s why it’s important to clean up or prevent zombie processes in production systems.


Preventing Zombie Processes

Let’s look at a couple of ways to prevent zombies from appearing.

Method 1: Use wait() or waitpid()

Here’s a revised version of our earlier program with proper cleanup:

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

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

    if (pid == 0) {
        printf("Child (PID: %d) exiting now.\n", getpid());
        exit(0);
    } else {
        wait(NULL); // Wait for child to finish
        printf("Parent (PID: %d) has reaped the child.\n", getpid());
    }

    return 0;
}

This ensures that the parent immediately collects the child’s status after termination.


Method 2: Use Signal Handlers

Instead of blocking on wait(), you can set up a signal handler for SIGCHLD:

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

void handle_sigchld(int sig) {
    wait(NULL); // Clean up child
}

int main() {
    signal(SIGCHLD, handle_sigchld);
    fork(); // Create child
    sleep(30); // Parent stays alive
    return 0;
}

This non-blocking way helps clean up child processes as soon as they exit.


Method 3: Ignore SIGCHLD

If you don’t care about the child’s exit status, you can ask the system to auto-clean them:

signal(SIGCHLD, SIG_IGN);

But note: this is not always safe or recommended in complex apps, especially those that need child process status.


Can You Kill a Zombie?

Technically, no — zombie processes are already dead.

Instead, your goal is to notify or terminate the parent process so it can collect the child’s exit code.

Step 1: Find the Zombie’s Parent

ps -o ppid= -p <Zombie_PID>

Step 2: Nudge the Parent with SIGCHLD

kill -s SIGCHLD <Parent_PID>

If that fails:

Step 3: Terminate the Parent

kill -9 <Parent_PID>

This allows the zombie to be reaped by init/systemd, which becomes its new parent.


Final Solution: Reboot

If zombie processes accumulate and their parent is already dead or misbehaving, a reboot may be the only solution to reclaim process table slots.


Summary


Bonus: Commands Cheat Sheet

Action Command
List zombies ps aux | grep Z
Find zombie parent ps -o ppid= -p <Zombie_PID>
Signal parent kill -s SIGCHLD <Parent_PID>
Force kill parent kill -9 <Parent_PID>
Reboot system sudo reboot

Thanks for reading!

Guneycan Sanli

Guneycan Sanli

Guneycan Sanli

A person who like learning, music, travelling and sports.

comments powered by Disqus