Skip to content

ci: give each virtual display helper its own serial - #14897

Merged
teamleaderleo merged 1 commit into
mainfrom
vdisplay-unique-serial
Sep 27, 2026
Merged

teamleaderleo merged 1 commit into
mainfrom
vdisplay-unique-serial

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

tests-build-and-lag fails its display churn setup on owned minis with ERROR: Failed to create CGVirtualDisplay (cmux9s 21:38Z, cmux13s 22:08Z and 01:24Z, cmux10s on 09-26).

WindowServer's log on cmux9s at the failure:

VirtualDisplay(CGXVirtualDisplayCreate) 0x1234/0x5678/0x1
Display V: 0x1234, P: 0x5678, S: 0x1 already exists!
VirtualDisplay(CGXVirtualDisplayCreate) no displayID available

A display created at 18:47Z (display 5) is still listed by system_profiler SPDisplaysDataType as "CI Virtual Display", and no helper process is alive. WindowServer kept it after its helper exited. The helper always used serial 0x0001, so every later create on that Mac fails until the GUI session restarts. cmux10s, cmux12s and cmux13s show the same leaked display.

Fix

  • scripts/create-virtual-display.m: the serial is the helper's pid (low 24 bits). If a leaked display already holds it, the helper tries three more serials (attempt number in the top byte).
  • scripts/ci/virtual-display-lock.sh: stray_helper_pids grepped for create-virtual-display and matched its own grep in ps. Every run printed "Reaping stray virtual-display helpers", waited 5 s, then kill -9'd a pid that had already exited. The pattern is now [c]reate-virtual-display.

The lag test passes the display id to the app, and nothing matches on the serial, so a new serial per run changes nothing else.

Tests

  • tests/test_ci_virtual_display_lock.sh passes.
  • The helper compiles with the same clang line CI uses. It was not run on a mini, because creating a display there would disturb a GUI job running on that Mac.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes the display churn setup in tests-build-and-lag failing on owned minis when WindowServer still lists a display whose helper process has exited.

WindowServer refuses a CGVirtualDisplay whose vendor/product/serial matches one it still lists, and it can keep a display after its helper exits, so the fixed serial 0x0001 blocked every later create until the GUI session restarted. The helper now uses its pid as the serial and tries three more values if a leaked display holds that one. virtual-display-lock.sh also stopped matching its own grep in ps, which made reap_strays wait 5 s and kill a pid that had already exited.

Written for commit 2b6fc3b. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • Improved virtual display startup reliability by trying alternate display identifiers when initialization fails.
    • Improved detection of virtual display helper processes, helping cleanup avoid mistaking its own search command for a helper process.

WindowServer refuses a CGVirtualDisplay whose vendor/product/serial matches a
display it still lists, and it can keep a display after the helper that made it
exits. On the owned minis (cmux9s, cmux10s, cmux13s) a display created at
11:47 local stayed listed with no helper alive, and every later create with the
fixed serial 0x0001 failed with "Display V: 0x1234, P: 0x5678, S: 0x1 already
exists!", so tests-build-and-lag failed its display churn setup twice per run.
The helper now uses its pid as the serial and tries three more if a leaked
display holds that one.

reap-strays also matched its own grep in ps, so it reported a stray on every
run, waited 5 s and then kill -9'd a pid that had already exited.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 99599946-aaed-4817-bdff-ebe8a9358e08

📥 Commits

Reviewing files that changed from the base of the PR and between a3baec3 and 2b6fc3b.

📒 Files selected for processing (2)
  • scripts/ci/virtual-display-lock.sh
  • scripts/create-virtual-display.m

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

Virtual display creation now tries up to four process-derived serials if initialization fails. Stray-helper detection uses a bracketed grep pattern to avoid matching the grep process itself.

Changes

Virtual display helper

Layer / File(s) Summary
Virtual display initialization retries
scripts/create-virtual-display.m
Initialization tries up to four serials derived from the process ID and attempt index. A zero serial becomes 1. If all attempts fail, the existing error path runs.
Stray helper process detection
scripts/ci/virtual-display-lock.sh
stray_helper_pids uses a bracketed grep pattern that excludes grep's own command line.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 2b6fc

The helper retries display creation and only signals readiness after configuration succeeds. No actionable merge-blocking risk is established.

Architecture Summary

Architecture risk: 🔵 Low · up to 2b6fc

The change affects 1 system.

Changed systems: scripts

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — scripts (service) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in scripts/ci/virtual-display-lock.sh: stray_helper_pids now searches with a bracketed pattern so grep does not match its own command line; the comments document that this avoids treating grep as a stray helper during reaping. The prior plain pattern could match the grep process itself.
  • observed — Modified behavior in scripts/create-virtual-display.m: The fixed serial 0x0001 and single initialization attempt were replaced with up to four attempts. Each attempt combines the process ID’s low 24 bits with the attempt index in the high byte; a zero serial becomes 1. Initialization stops on success, and failure after all attempts follows the existing error path.
🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: assigning unique serials to virtual display helpers. It is concise and specific, although it does not mention the related grep fix.
Description check ✅ Passed The description explains the failure, the serial-retry fix, the grep fix, and the testing performed. It uses Problem, Fix, and Tests headings instead of the template headings and omits the checklist, …
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. (1 skipped: 1 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Cloud Persistent Session And Early Input ✅ Passed The pull request changes only virtual-display CI scripts. The diff does not modify Cloud terminal creation, cmux-tui transport, manual renderers, input routing, authentication, idempotency, revision f…
Cmux Swift Actor Isolation ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. The authoritative diff contains no Swift files or Swift actor-isolation changes, so thi…
Cmux Swift Blocking Runtime ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. No Swift file or production Swift code changed, so this custom check does not apply. Th…
Cmux Browser Automation Off-Main ✅ Passed The pull request changes only virtual display serial allocation and stray-helper PID filtering. The diff contains no browser socket automation commands, WebKit/AppKit browser callbacks, `socketWorkerM…
Cmux Expensive Synchronous Load ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. Neither file is Swift, and the patch adds no agent-history, transcript, JSONL, or works…
Cmux Cache Substitution Correctness ✅ Passed PASS — The pull request changes only Objective-C (scripts/create-virtual-display.m) and shell (scripts/ci/virtual-display-lock.sh) files. It introduces no production Swift, TypeScript, or JavaScri…
Cmux No Hacky Sleeps ✅ Passed The diff does not introduce or worsen a hacky sleep. The shell sleep calls and polling loop are unchanged. The new comment only describes the old false-positive behavior. The Objective-C helper adds…
Cmux Algorithmic Complexity ✅ Passed No algorithmic-complexity failure is introduced. The new display-creation retry loop has an explicit fixed bound of four attempts. The shell change only replaces a grep pattern; it does not add a nest…
Cmux Swift Concurrency ✅ Passed PASS: The authoritative pull-request diff changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It introduces no Swift code and therefore cannot introduce or expand…
Cmux Swift @Concurrent ✅ Passed PASS: The review-scoped diff changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It contains no Swift files, async Swift functions, or @concurrent annotations…
Cmux Swift Package Boundaries ✅ Passed The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. The latter is Objective-C, not Swift, and the changes add virtual-display serial handling. No…
Cmux Swiftpm Lockfiles ✅ Passed PASS: The PR changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It does not change a SwiftPM package, Package.resolved, .gitignore, workflow, dependency decl…
Cmux Swift Logging ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It contains no production Swift changes, so the Swift logging rule does not apply.
Cmux User-Facing Error Privacy ✅ Passed PASS. The diff changes only the CI virtual-display lock script and the create-virtual-display.m helper. Their outputs and errors serve CI jobs and test harnesses, not a cmux app UI, product CLI, or …
Cmux Full Internationalization ✅ Passed PASS. The PR changes only CI support scripts and the Objective-C virtual-display test helper. The added text is developer-only comments; existing helper diagnostics and output are unchanged. No Swift …
Cmux Swiftui State Layout ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. The diff contains shell and Objective-C virtual-display logic, with no Swift, SwiftUI, …
Cmux Architecture Rethink ✅ Passed PASS: The pull request changes only a shell script and an Objective-C .m helper. It changes no Swift files. The cited rule applies to Swift architectural changes, so its failure conditions do not ap…
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PASS: The authoritative PR diff changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It adds no Swift, NSWindow, NSPanel, NSWindowController, SwiftUI Window, or Wi…
Cmux Source Artifacts ✅ Passed Both changed paths are hand-written source scripts: scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. The diff changes process matching and virtual-display serial creation. …
Cmux No Test Or Debug Seam In Production Source ✅ Passed PASS: The pull request changes only scripts/ci/virtual-display-lock.sh and scripts/create-virtual-display.m. It changes no Swift file under a production Sources/ path, so the custom check does n…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@teamleaderleo
teamleaderleo merged commit 2e6a5ba into main Sep 27, 2026
64 of 65 checks passed
@teamleaderleo
teamleaderleo deleted the vdisplay-unique-serial branch September 27, 2026 03:46
@github-actions

Copy link
Copy Markdown
Contributor

Merge receipt for 2b6fc3bdb6: every check was green at merge (15 verified; 15 skipped by policy). Full suite runs on main after merge.

rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 27, 2026
f77bfdd Show a password input indicator while echo is off (manaflow-ai#14867)
ec04960 web tests: spawn client-config-env children asynchronously (manaflow-ai#14899)
f10c5ce test: say why the portal fixture's scrollback wait failed (manaflow-ai#14898)
2e6a5ba ci: give each virtual display helper its own serial (manaflow-ai#14897)
208a6bf Keep the unfocused-pane dim in step with focus when a pane is revealed (manaflow-ai#14892)
33b4c92 fix: finish a detach-induced checklist popover close without its animation (manaflow-ai#14895)
a3baec3 test: free the remaining hosted test terminals and scope the portal leak check (manaflow-ai#14888)
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.

1 participant