Skip to content

fix: sweep the child's process group after every phase - #650

Open
ykhrustalev wants to merge 2 commits into
sourcefrog:mainfrom
ykhrustalev:ykhrustalev/sweep-process-group
Open

ykhrustalev wants to merge 2 commits into
sourcefrog:mainfrom
ykhrustalev:ykhrustalev/sweep-process-group

Conversation

@ykhrustalev

Copy link
Copy Markdown

Problem
Tests can leave processes running after they exit — a helper a test spawned and forgot, or a test binary that was never reaped. The child's process group was only signalled on a timeout, so on a normal exit those survived and kept allocating while later mutants were tested, in a window where no cargo phase was running at all.

Solution

  • Sweeps the cargo process group after every phase, not only on timeout: SIGTERM, a bounded grace period, then SIGKILL.
  • Records what was reaped in the scenario log, and the pids (enumerated from /proc on Linux) at debug level.
  • Probes the group before enumerating it, so the common no-strays case costs one killpg(…, 0) rather than a /proc walk.
  • No-op on Windows, which has no process groups (job objects would be the equivalent; out of scope).

Testing

  • New spawns_background_child tree: its test leaves sleep 300 running and records the pid; the integration test probes the pid afterwards and checks every mutant's verdict is unchanged. Fails against main.

Stacked on #648; only the last commit is new here. Split out of #647 as requested.

On a timeout, terminate_child() sent one SIGTERM and then blocked in wait()
with no bound. A cargo process that ignores the signal, or that has been
stopped and so never receives it, hung the whole run at that point.

Wait only for a short grace period, then SIGKILL the process group. This
needs a second signal, so the errno handling moves into a signal_group()
helper rather than being duplicated.
Tests can leave processes running after they exit: a helper a test spawned and
forgot, or a test binary that was never reaped. Until now cargo-mutants only
signalled the child's process group on a timeout, so on a normal exit those
processes survived and kept allocating while later mutants were tested, in a
window where no cargo phase is running at all.

Sweep the group in the process layer, so every phase gets it: once the direct
child exits with any status, SIGTERM the group, wait a bounded grace period,
then SIGKILL whatever is left. What was reaped goes into the scenario log, and
the pids into the debug log, enumerated from /proc on Linux.

Windows has no process groups and the job object equivalent is out of scope,
so the sweep is a no-op there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant