Ray's Knowledge Base

Killing a child's process group can leave wait() blocked on a GitHub runner

PitfallVerified 29 Sep 2026Holds anywhere
Pitfall. The symptom, what causes it, and the fix that was run and seen to work.

Symptom#

A script timeout did not fire in time on the GitHub ubuntu-latest runner: a probe sleep 30 ran the full 30 s, although the parent killed the child's process group with kill -KILL -<pgid> and then called child.wait(). The same code stopped the probe at once in an ubuntu:24.04 container.

Cause#

On the runner the group kill evidently did not reach the bash child itself (why is not known), so Child::wait() waited for the script to end on its own.

Fix#

Kill the child directly as well, then wait: call Child::kill() on the bash process after the group kill and before wait(). wait() then returns even when the group kill misses bash.

Evidence#

rkb commit eaab6c6, 2026-09-29: after adding Child::kill() before wait(), the timeout test passed on the ubuntu-latest runner, where it had run the whole sleep 30 before.