benfred/py-spy · error
failed to get subprocesses
Error message
failed to get subprocesses
What it means
In Sampler::new_subprocess_sampler, a background thread periodically calls process.child_processes() to discover new child interpreters while recording with --subprocesses. A failed enumeration panics on that thread with "failed to get subprocesses", aborting the sampling session.
Source
Thrown at src/sampler.rs:155
"No python processes found in process {} or any of its subprocesses",
pid
));
}
std::thread::sleep(std::time::Duration::from_millis(100));
}
// Create a new thread to periodically monitor for new child processes, and update
// the procesess map
let spies = Arc::new(Mutex::new(spies));
let monitor_spies = spies.clone();
let monitor_config = config.clone();
std::thread::spawn(move || {
while process.exe().is_ok() {
match monitor_spies.lock() {
Ok(mut spies) => {
for (childpid, parentpid) in process
.child_processes()
.expect("failed to get subprocesses")
{
if spies.contains_key(&childpid) {
continue;
}
match PythonSpyThread::new(childpid, Some(parentpid), &monitor_config) {
Ok(spy) => {
spies.insert(childpid, spy);
}
Err(e) => {
warn!("Failed to create spy for {}: {}", childpid, e);
}
}
}
}
Err(e) => {
error!("Failed to acquire lock: {}", e);
}
}View on GitHub (pinned to 32080cc0c2)
Solutions
- Keep the parent process alive for the whole recording window (record the actual server, not a shell wrapper that spawns it).
- Run py-spy with sudo/Administrator for the entire recording so child process metadata stays readable.
- Retry the recording; transient target exit mid-session is the most common cause.
- Record a specific child pid without --subprocesses if the tree churns constantly.
Example fix
// before: recording a shell wrapper that exits when children die py-spy record --subprocesses -o p.svg -- ./run_workers.sh // after: record the long-lived parent directly WORKER_PID=$(pgrep -f worker.py | head -1) sudo py-spy record --subprocesses -o p.svg --pid $WORKER_PID --duration 60
Defensive patterns
Strategy: retry
Validate before calling
# ensure parent stays alive and we can read its children
kill -0 "$PID" 2>/dev/null || { echo "target exited" >&2; exit 1; }
ls /proc/$PID/task >/dev/null 2>&1 || { echo 'no permission on /proc target'; exit 1; } Try / catch
for i in 1 2 3; do sudo py-spy record --pid "$PID" --subprocesses -o p.svg --duration 60 && break pgrep -f worker.py >/dev/null || break # don't retry if target tree is gone sleep 2 done
Prevention
- Record a long-lived parent (server process), not shell wrappers that exit with their children.
- Hold root/Administrator privileges for the full recording duration.
- Re-check the target is alive before retrying failed recordings.
When it happens
Trigger: Running `py-spy record --subprocesses` when child_processes() fails during sampling — the target or its children exited mid-record, permissions on process metadata changed, or an OS enumeration API returned an error mid-session.
Common situations: Long recordings where the parent exits after children finish (common with shell wrappers), jobs that kill/restart worker processes, or recordings started as root that lose privileges or vice versa.
Related errors
AI-assisted analysis of benfred/py-spy@32080cc0c2 (2026-09-05).
Data as JSON: /api/errors/4c52f2cdf2fea952.
Report an issue: GitHub.