Skip to content

fix: shpool kill: ignore missing target process - #405

Open
dob323 wants to merge 1 commit into
shell-pool:masterfrom
dob323:fix/kill-dead-shell-esrch
Open

fix: shpool kill: ignore missing target process#405
dob323 wants to merge 1 commit into
shell-pool:masterfrom
dob323:fix/kill-dead-shell-esrch

Conversation

@dob323

@dob323 dob323 commented Aug 3, 2026

Copy link
Copy Markdown

Issue Link

(none)

AI Policy Ack

I have read the AI Policy. This patch was written with Claude Code, working from failures in my own shpool deployment. Test coverage was added during review: kill::already_dead_shell, which fails without the fix.

This PR was:

  • mostly or completely vibe coded
  • mostly or completely meat coded
  • bit of both

Description

Session::kill() propagates ESRCH from the SIGHUP as an error, and
handle_kill then aborts before removing the session from the shells
table. A session whose child exited on its own (crash, external kill,
missed reap) therefore becomes a phantom: shpool list keeps advertising
it, attach fails, and no kill can ever remove it until the daemon
restarts.

Log signature:

ERROR ... handling new connection: killing shell proc
Caused by:
    0: sending SIGHUP to child proc
    1: ESRCH: No such process

Reproduce on stock 0.11.0: kill -9 a session's shell process, then
shpool kill that session.

This treats ESRCH as the state kill exists to reach, at both the SIGHUP
and SIGKILL-escalation sites.

@google-cla

google-cla Bot commented Aug 3, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ethanpailes

Copy link
Copy Markdown
Contributor

Please don't just delete the PR template, it is there for a reason. In this case, I would like to know your use of AI to generate this patch.

// long-dead child as an error leaves an unkillable phantom session
// that haunts the list until a daemon restart.
match signal::kill(Pid::from_raw(self.child_pid), Some(signal::Signal::SIGHUP)) {
Err(nix::errno::Errno::ESRCH) => return Ok(()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not that common a code to work with, so let's document it as "no such process" in a comment.

Comment thread libshpool/src/daemon/shell.rs Outdated
// but for shells SIGHUP serves as the graceful shutdown signal.
signal::kill(Pid::from_raw(self.child_pid), Some(signal::Signal::SIGHUP))
.context("sending SIGHUP to child proc")?;
// A child that is already gone is exactly the state kill exists to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please delete this whole comment block in favor of just documenting what the code means. It should be clear from context why we ignore ESRCH if we explain what it means. This comment block reads like an AI report about the bug injected into the patch, but I don't think it is worth adding a big comment about this over the long term.

@ethanpailes

Copy link
Copy Markdown
Contributor

Looks pretty good, please sign the CLA and disclose your AI use.

@ethanpailes ethanpailes changed the title daemon: a kill target whose child already exited is a success fix: shpool kill: ignore missing target process Aug 3, 2026
@dob323
dob323 force-pushed the fix/kill-dead-shell-esrch branch from 47c6a07 to 55f3e88 Compare August 6, 2026 19:19
@dob323

dob323 commented Aug 6, 2026

Copy link
Copy Markdown
Author

@googlebot I signed it!

@ethanpailes

Copy link
Copy Markdown
Contributor

Looks like CLA bot is still grumpy. Also, can you add a test for this. The regression or kill test suites are probably good places to put one.

@dob323
dob323 force-pushed the fix/kill-dead-shell-esrch branch 2 times, most recently from fc848ed to 3857db4 Compare August 6, 2026 20:04
@dob323

dob323 commented Aug 6, 2026

Copy link
Copy Markdown
Author

Sorry, I missed your test requests from Friday. All three have tests now:

Each one fails on master and passes with its patch.

Also addressed both review comments: dropped the comment block and documented ESRCH as "no such process" at each call site.

@ethanpailes ethanpailes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, just one last nit about redundancy in the support file.

Comment thread shpool/tests/support/line_matcher.rs Outdated
}

/// Scan lines until one matches the given regex, returning its captures.
pub fn scan_until_captures_re(&mut self, re: &str) -> anyhow::Result<Vec<Option<String>>> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty redundant with scan_until_re. Let's implement scan_until_re in terms of this routine. I know there is overhead to getting capture groups, but it is pretty small. Also let's call this scan_until_re_captures instead because we're still scanning until the whole regex matches and just extractng the groups afterwards.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, renamed to scan_until_re_captures and scan_until_re now just calls it and drops the captures.

If the shell is already gone, kill fails on ESRCH and the error stops the
daemon from removing the session from its table, so the session can never
be killed and lingers until the daemon restarts.

Covered by kill::already_dead_shell.
@dob323
dob323 force-pushed the fix/kill-dead-shell-esrch branch from 3857db4 to 74f7286 Compare August 6, 2026 20:17
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.

2 participants