Fix process tree termination races - #12
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d409b1bba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| |child| is_valid_process_tree_edge(parent, *child, snapshot_time_100ns), | ||
| ) { | ||
| DescendantProcessOutcome::Verified(child) => child, | ||
| DescendantProcessOutcome::GoneOrReused => continue, |
There was a problem hiding this comment.
Report vanished intermediate nodes instead of skipping their subtree
When a snapshotted intermediate process exits before this query but one of its children remains alive, this continue skips recursion into that intermediate node, so the surviving grandchild is never verified or opened; the root can then be terminated and kill_process_tree reports success even though part of the snapshotted tree remains. The new stress test only creates direct short-lived children and does not cover this case. Preserve enough verified state to traverse surviving descendants, or report that the tree could not be fully prepared rather than silently abandoning the branch.
AGENTS.md reference: AGENTS.md:L120-L125
Useful? React with 👍 / 👎.
Summary
TerminateProcessas benign only when the handle is already signaledRoot cause
The process-tree path propagated every descendant
ERROR_INVALID_PARAMETERas fatal even though that code also represents the expected races where a snapshotted process exits or a captured PID is reused. A second race existed after handles were opened:TerminateProcessfailure was counted unconditionally even when the process had already exited naturally.Impact
End Process Treecontinues terminating the verified root and all still-verifiable descendants when short-lived descendants disappear. PID reuse remains protected by creation-time validation, and access-denied or unexpected errors are still reported before any termination starts.Validation
rustfmt 1.9.0on the changed Rust files, followed by--check-D warningsforx86_64-pc-windows-msvc-D warningsfori686-pc-windows-msvc-D warningsforaarch64-pc-windows-msvccargo check --all-targets --lockedforx86_64-pc-windows-msvcgit diff --checkCloses #11