Skip to content
Back to skills

Zombie Process Cleanup

ASecurity

Detecting and reaping zombie/orphan processes in agent sandboxes. SIGCHLD handling, waitpid reaping, subreaper patterns, and Node.js child_process cleanup. Sources: node-modules/zombie, Linux waitpid(2) man page.

  • 10 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 9, 2026
ai-agentsjavascriptjavabashnodeapi

Works with

  • api

Security analysis

A100/100

Scanned September 9, 2026

npx -y skills add yanacuti1121/Yana-AI --skill zombie-process-cleanup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Zombie Process Cleanup?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Zombie Process Cleanup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yanacuti1121-zombie-process-cleanup/badge)](https://www.skillsdirectory.com/skills/yanacuti1121-zombie-process-cleanup)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: zombie-process-cleanup
description: Detecting and reaping zombie/orphan processes in agent sandboxes. SIGCHLD handling, waitpid reaping, subreaper patterns, and Node.js child_process cleanup. Sources: node-modules/zombie, Linux waitpid(2) man page.
origin: yana-ai — synthesized from node-modules/zombie (MIT), Linux process lifecycle docs
license: Apache-2.0
version: 1.0.0
compatibility: yana-ai >= 1.3.48
---

# /zombie-process-cleanup

## When to Use

- Agent spawns many short-lived subprocesses that become zombies
- Sandbox PID namespace filling up with defunct processes
- Long-running agent sessions accumulating dead children
- Implementing a sub-reaper for an isolated PID namespace

## Do NOT use for

- Processes still running (zombies are already dead, just not reaped)
- Kernel threads (not reapable from userspace)

---

## Node.js child_process cleanup

```javascript
import { spawn } from 'child_process'

// Always attach handlers — unhandled children become zombies
function spawnSafe(cmd: string, args: string[]): Promise<number> {
  return new Promise((resolve, reject) => {
    const child = spawn(cmd, args, {
      detached: false,    // stay in process group
      stdio: 'pipe',
    })

    child.on('error', reject)
    child.on('close', (code, signal) => {
      // close fires after all stdio closed + process exited → fully reaped
      resolve(code ?? (signal ? 128 : 0))
    })

    // Kill child if parent exits unexpectedly
    process.on('exit', () => { try { child.kill('SIGTERM') } catch {} })
  })
}
```

---

## Bash sub-reaper (PID namespace)

```bash
#!/usr/bin/env bash
# reaper.sh — act as init inside a PID namespace
# Linux: set subreaper flag via prctl PR_SET_CHILD_SUBREAPER

# Trap SIGCHLD and reap all terminated children
reap_children() {
  while true; do
    # waitpid -1 = any child; WNOHANG = don't block
    wait -n 2>/dev/null || break
  done
}
trap reap_children SIGCHLD

# Run the actual payload
"$@" &
MAIN_PID=$!

# Wait for main process
wait "$MAIN_PID"
MAIN_EXIT=$?

# Final reap pass
reap_children

exit "$MAIN_EXIT"
```

---

## Detect zombies

```bash
# List all zombie processes in current namespace
detect_zombies() {
  local zombies
  zombies=$(ps -eo pid,ppid,stat,comm | awk '$3~/^Z/{print}')
  if [[ -n "$zombies" ]]; then
    echo "[zombie] Detected defunct processes:" >&2
    echo "$zombies" >&2
    return 1
  fi
  return 0
}

# Reap zombies owned by current process tree
reap_my_children() {
  while IFS= read -r pid; do
    wait "$pid" 2>/dev/null && echo "[reap] reaped PID $pid"
  done < <(ps -eo pid,ppid,stat | awk -v me="$$" '$2==me && $3~/^Z/{print $1}')
}
```

---

## Anti-Fake-Pass Checklist

```
❌ spawn() with detached:true but no unref() → child still prevents parent exit
❌ No close handler → process reaped by OS eventually but leak accumulates
❌ exec() without fork → replaces parent, no child to reap
❌ Zombie reaping requires the parent (not grandparent) to call wait()
❌ PID namespace without subreaper → orphans reparent to PID 1 (container init)
❌ SIGCHLD ignored (SIG_IGN) on Linux auto-reaps but breaks wait() return codes
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.