Repository navigation
fix(logs): keep an early iOS simulator logs stop from hanging the session - #3892
Conversation
Size Report
Startup median (7 runs, lower is better):
|
|
…sion `xcrun simctl spawn` forwards a stop signal to the in-simulator `log stream` only after the launch completes. A `logs stop` sent during the launch ended simctl, the orphaned stream kept the output pipes open, and the managed wait never settled, so the stop and every later session request hung. Simulator `logs start` now returns once the stream writes its first output, and managed app-log termination releases output pipes that a process outside the child's tree still holds after the child exits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A simulator log stream that never writes output now fails logs start with reason simulator-log-stream-launch-timeout after 10 s instead of holding the session until the client envelope resets the daemon. The process-host test double now models a child that exits while a descendant keeps its pipes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0d3c327 to
5f9f5f2
Compare
|
The fix looks correct at 5f9f5f2. I found nothing that needs a change before merge, but the live evidence is still short of what I can confirm. The reported live runs were at 0d3c327, and I could not confirm they match the rebased patch. No run artifacts are linked. Please link them, or rerun on 5f9f5f2 and show that an early I did not run the tests. I judged that they fail on the base by reading the base code paths. The escaped-descendant test mocks Not blocking: host-kit already owns the rule that a killed command settles when its direct child exits, in createCommandKillSettlement, while the managed host kills the child directly and adds a timer-based stream destroy beside it. Also, the docs line at commands.md:1065 says "On iOS simulators", but the gate in start.ts covers every Apple simulator, so "Apple simulators" is more accurate. You can take or leave both. Could the readiness gate in start.ts stay as it is, and termination abort a per-process AbortController passed to Lint, Typecheck & Package fails on the line cap in |
…log host Drive the escaped-descendant termination test through the real runCmdBackground with a shell whose background loop keeps the inherited pipes open, so it exercises Node's close on stream release. Name the simulator gate after every Apple simulator in the docs and error text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Follow-up for the 2026-10-22 review. Head is now 1. Live evidence at Setup: own iPhone 17 Pro simulator, iOS 27.0, Xcode 27.1 (27A9275),
Request logs are kept only for failed requests. All 12 (the timeout, the 6 cancels, the 3 Readiness signal and quiet predicates. On Xcode 27.1 / iOS 27.0, the first bytes from the in-simulator 2. Host-kit kill settlement I kept the current approach. Concretely:
On test fidelity: I replaced the hand-built-wait test. The new test goes through the real 3. Docs: applied. The line now says "On Apple simulators". I also renamed the timeout message from "iOS simulator log stream…" to "Simulator log stream…" for the same reason. Validation: Raw per-run summary: start → 400 ms → stop → appstate (24 runs)
Raw per-run summary: mid-launch cancels (client killed after delay_ms)Exit 143 means the harness killed the client with SIGTERM. Restart exit 1 in runs 3 and 6 is Run 21 launch-timeout response{"code":"COMMAND_FAILED","message":"Simulator log stream did not start within 10000ms","hint":"Check that the simulator finished booting, then retry logs start.","details":{"reason":"simulator-log-stream-launch-timeout","timeoutMs":10000}}Request log: |
|
The findings from the earlier review are fixed at 872985b, and I found no new problems in the code. I did not run the new escaped-descendant test or any other test. I judged it from the close-only settle path in host-kit at this commit. The live runs are the author's, with inline summaries. I could not re-run them, and no artifacts are linked. The readiness signal (first output byte from the in-simulator log process) is checked only on Xcode 27.1 and iOS 27.0, so older runtimes such as the iOS 26.2 runtime in CI are not covered. The author's run under host load of about 500 on 12 cores had 1 of 24 launches pass the 10 s deadline and fail with the typed reason. That is correct behavior, but the deadline's headroom on loaded CI hosts is not measured. Smoke Tests is still running and has not failed. The iOS smoke route replays |
Summary
On an Apple simulator, a
logs stopsent ~400 ms afterlogs startcould hang the session (found by #3885).Root cause:
simctl spawn … log streamforwards a stop signal only after the in-simulatorlogprocess has launched. An earlier SIGINT ended simctl, and the orphanedlogprocess kept the output pipes open, so the managed app-logwaitnever settled.logs startreturns once the stream writes output. If that takes more than 10 s, it fails withdetails.reason: "simulator-log-stream-launch-timeout".6 files plus a
commands.mdnote.Validation
Head
872985b93d.872985b93d(iOS 27.0 sim, Xcode 27.1, host load 380–930 on 12 cores), see this comment:appstate: 24 runs. Stop never hung: 0.8 / 1.8 / 6.2 s (min/median/max). 0 in-sim and 0 host leftovers.0d3c327, baseb74fcebdc1hung 2 times in 10 runs.check:affected --run --head 872985b93d: format, lint, and typecheck passed. Vitest passed 1299/1300. Its one failure (apple-platform-output-guardrecordtimeout) also fails on maine3ed027a1dat load ~900. CI Integration Tests passes.🤖 Generated with Claude Code