Source
Flagged during the thermo-nuclear review of #398 / #399 in rust/src/host/command_runner.rs.
Problem
In CommandRunner::run() (~line 159), capture_output is invoked via ? on the stdout/stderr reader handles. If this errors, run propagates the error immediately and the Child is dropped without kill() or wait() being called — on Unix this leaves an unreaped zombie process until the parent exits.
This is a sibling of the error path fixed in #399 (where finish_child's Err arm fell through to teardown). The finish_child function itself is now correct on all paths; the remaining gap is the early ? in run() that bypasses finish_child entirely.
Suggested fix
Wrap the capture_output call so that on error, the child is torn down (kill + wait) before propagating — e.g. match capture_output(...) { Ok(v) => v, Err(e) => { finish_child(&mut child); return Err(e); } } or an equivalent guard.
Context
Source
Flagged during the thermo-nuclear review of #398 / #399 in
rust/src/host/command_runner.rs.Problem
In
CommandRunner::run()(~line 159),capture_outputis invoked via?on the stdout/stderr reader handles. If this errors,runpropagates the error immediately and theChildis dropped withoutkill()orwait()being called — on Unix this leaves an unreaped zombie process until the parent exits.This is a sibling of the error path fixed in #399 (where
finish_child'sErrarm fell through to teardown). Thefinish_childfunction itself is now correct on all paths; the remaining gap is the early?inrun()that bypassesfinish_childentirely.Suggested fix
Wrap the
capture_outputcall so that on error, the child is torn down (kill + wait) before propagating — e.g.match capture_output(...) { Ok(v) => v, Err(e) => { finish_child(&mut child); return Err(e); } }or an equivalent guard.Context
finish_child(command_runner.rs:269-294) is the canonical teardown — reuses it if possible