# Start several background processes with different durations
terminal("sleep 10", background=true) # → PID 393
terminal("sleep 65", background=true) # → PID 412
terminal("sleep 73", background=true) # → PID 435
terminal("sleep 300", background=true) # → PID 9
# Wait for the short ones to finish, then check:
process(action="list")
# Reports all 4 as "running" ✅
# But ps auxwww shows:
# PID 9 sleep 300 running ✅
# PID 393 [bash] <defunct> zombie ❌
# PID 412 [bash] <defunct> zombie ❌
# PID 435 [bash] <defunct> zombie ❌
Bug
Background processes started with
terminal(background=true)become zombies (<defunct>) when they exit. Theprocesstool continues to report them as "running" because it tracks the wrapper PID without checking if it's a zombie.Reproduction
Root cause
Two compounding issues:
No zombie reaping. The sandbox container's PID 1 is
sleep 2h(fromdocker run ... sleep 2h), not an init process. It doesn't callwait()on orphaned children, so completed background processes become zombies instead of being reaped.processtool doesn't check process state.ProcessRegistrytracks wrapper PIDs and reports them as "running" based on whether the PID exists, without checking/proc/<pid>/statusfor zombie state. A zombie PID still exists (it's in the process table until reaped) so the registry incorrectly reports it as alive.Expected behavior
process(action="list")should show completed processes as "exited" with their exit code.process(action="poll")on a completed process should return its final output + exit status.Possible fixes
--initflag ondocker run(addstinias PID 1) so orphaned children are reaped automatically.os.waitpid(pid, os.WNOHANG)on poll/list to detect and reap zombies.--initfor the container-level fix,waitpidfor the registry-level fix.Environment
sleep 2h(not an init process)tools/process_registry.py