Proper zombie process handling

This is part of the psutil 3.0 release (see the full release notes).

Except on Linux and Windows (which does not have them), support for zombie processes was broken. The full story is in #428.

The problem

Say you create a zombie process and instantiate a Process for it:

import os, time

def create_zombie():
    pid = os.fork()  # the zombie
    if pid == 0:
        os._exit(0)  # child exits immediately
    else:
        time.sleep(1000)  # parent does NOT call wait()

pid = create_zombie()
p = psutil.Process(pid)

Up until psutil 2.X, every time you tried to query it you’d get a NoSuchProcess exception:

>>> p.name()
  File "psutil/__init__.py", line 374, in _init
    raise NoSuchProcess(pid, None, msg)
psutil.NoSuchProcess: no process found with pid 123

This was misleading, because the PID technically still existed:

Depending on the platform, some process information could still be retrieved:

>>> p.cmdline()
['python']

Worst of all, psutil.process_iter() didn’t return zombies at all. That was a real problem, because identifying them is a legitimate use case: a zombie usually indicates a bug where a parent process spawns a child, kills it, but never calls wait() to reap it.

What changed

import psutil

zombies = []
for p in psutil.process_iter():
    try:
        if p.status() == psutil.STATUS_ZOMBIE:
            zombies.append(p)
    except psutil.NoSuchProcess:
        pass