Fix ConnManager exit code race - #201
Conversation
Prefer an already-recorded process exit code when serve cancellation races process exit, so HMP clients do not receive the default exit code 0 after a non-zero process exit. Add deterministic coverage for the timing path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a timing-sensitive race in ConnManager where a recorded non-zero process exit code could be dropped when process exit raced serve-context cancellation, causing HMP clients to receive the default exit code 0. Previously, the exit-code feeder goroutine used a single select between ExitHandler.Exited() and serveCtx.Done(); when cancellation won the race, it closed exitCodeCh without ever sending the code. The refactor extracts the feeder logic into a testable helper that prefers an already-available exit result even when the serve context is also canceled.
Changes:
- Extracted the exit-code feeding logic into
sendProcessExitCode/sendExitCodehelpers, adding an innerselectthat re-checksExited()whenserveCtx.Done()fires so an already-recorded exit code is still forwarded. - Added
processpackage import toconn_manager.go. - Added a deterministic regression test (
TestSendProcessExitCodePrefersExitedProcessAfterServeCancel) that exercises the both-ready timing scenario.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| internal/termpty/conn_manager.go | Splits the exit-code feeder into sendProcessExitCode/sendExitCode; the cancellation branch now re-checks Exited() so a recorded exit code is forwarded instead of dropped. |
| internal/termpty/conn_manager_test.go | Adds a regression test asserting the recorded exit code is sent when process exit and serve cancellation are both ready. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
/backport to release/0.25 |
|
Started backporting to release/0.25: https://github.com/microsoft/dcp/actions/runs/28544273580 |
|
David Negstad (@danegsta) backport PR couldn't be created automatically, please create the backport PR manually! |
ConnManager could drop a recorded non-zero process exit code when process exit raced serve cancellation, causing HMP clients to receive the default exit code 0.
This updates the exit-code feeder to prefer an already-available
ExitHandlerresult even when the serve context is also canceled. The helper is split out so the timing-sensitive path has deterministic regression coverage.Validation:
make test-prereqsgo test -count 1 -parallel 32 ./internal/termptymake testmake lintFixes: #199