Closing a pane right after starting it can leave its program running (stray shims from tests) #35
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closing a pane right after starting it can leave its program running with no daemon. It's seen as stray
illogicald _shim … -- bash --norc --noprofile -c sleep 600processes (parent pid 1) piling up on jake-mini, where a CI runner runs the test suite (~/.cache/illogical-ci). Each one lives until its program exits on its own; for that test, 10 minutes.Reproduce (macOS, main at
b6ac5be)It's
api.rs's "a script can close what it opened, even while it's running":POST /api/run {"command": "sleep 600"}, then at oncePOST /api/panes/N/close, then the test ends and kills its daemon.The stray
sleepis a session leader with the pane's terminal as its controlling tty (Ss+). No process holds the PTY master any more, and a SIGHUP sent by hand kills it. So the daemon's hangup never reached it.Why (likely)
shim::runforks, and the parent appendspid <pid> <start>at once. The child callssetsid()and then execs, but possibly after the record is written. The daemon reads the record, considers the program started, and aclosearriving now runshang_up(), which callskillpg(pid, SIGHUP). Before the child'ssetsid()no process grouppidexists, so the signal is lost (ESRCH).hang_up()sends SIGKILL to the group 3 s later from a daemon thread. If the daemon dies first (the test ends; a real daemon stops or crashes), it never happens.Linux likely has the same race, but it hasn't been seen there.
Fix
setsid()andTIOCSCTTY, and it closes onexec. The parent waits for EOF (or for an exec-failure byte) before recording the pid. Then whatever the daemon signals by pid or group exists.hang_upsignals the shim too, and the shim escalates.Daemonhelpers'Drop(api.rs,attach.rs,fs.rs,agents, …) kills the process group of everypidrecorded under its state dir'sblocks/*/processbefore deleting the dir. Then no test run leaves programs behind, whatever the daemon does.Done when
cargo test -p illogicald --test apion macOS and Linux leave no_shimor program processes behind.runand asserts the program is gone within a few seconds, with the daemon killed right after the close.