Skip to content

[macOS desktop] Accumulated tool pipes stall Xcode compiler discovery; restart/update restores pipe capacity #51148

Open

Description

@ksanderer

What version of the Codex App are you using?

Before recovery: ChatGPT desktop hosting Codex, version 26.928.21956, build 12404.
After recovery: version 26.928.31416, build 12553.

Versions were read from app bundle metadata. Restart also changed the installed app version; this is not a controlled same-version restart experiment.

What subscription do you have?

Not disclosed for privacy; no account or billing data is included.

What platform is your computer?

macOS 26.5.1 (25F80), Apple Silicon / arm64.
Xcode 26.6 (17F113); Apple clang 21.0.0 (clang-2100.1.1.101); macOS SDK 26.5.

What issue are you seeing?

After approximately five days of desktop uptime, Xcode builds stalled at Planning / Discovering version info for clang, before compiling any application source. Terminal xcodebuild also stalled at compiler discovery with signing disabled. Restarting only the build service did not resolve the problem.

Fresh nonblocking pipes could accept only 512 bytes and would not expand. Most observed PIPE file descriptors belonged to the desktop app's descendant process tree. After restarting/updating the desktop app, pipe capacity and compiler controls recovered; the application build also succeeded according to the user.

Measurement Before restart/update After restart/update
System-visible PIPE file descriptors 4,351 871
Processes in desktop app tree, including root 546 26
PIPE descriptors in desktop app tree 3,622 119
PIPE descriptors outside that tree 729 752
Fresh pipe usable capacity 512 bytes 65,536 bytes
clang with concurrent stdout/stderr collection Exit 0, 0.0148 s Exit 0, 0.0108 s
clang with sequential stdout/stderr collection Timeout after 5 s Exit 0, 0.0321 s

Before recovery, the app tree contained 169 bundled CUA node processes, 102 node_repl processes, and 51 launcher/server pairs for chrome-devtools-mcp. One bundled Codex server held 923 PIPE descriptors. Expected process counts for persistent chats were not established.

These are descriptor endpoints, not unique pipes or allocated pipe-buffer bytes. Process-tree attribution includes tools/plugins and transient diagnostics. Snapshot counts alone do not prove a leak.

What steps can reproduce the bug?

The exact trigger for accumulating the desktop resources has not been isolated. The following diagnostic reproduces the downstream compiler deadlock while the affected pipe-pressure state is present, without accessing an application project, private source or account data.

  1. In a long-running desktop session with many tool runtimes, measure process/PIPE counts using ps and lsof locally. Do not publish raw output.
  2. Run this diagnostic. Before recovery it reports 512-byte pipe capacity, successful concurrent collection, and a sequential-collection timeout. After recovery it reports 65,536-byte capacity and successful collection in both modes.
  3. Restart the desktop app and repeat. Record app versions before/after to distinguish restart from update. Keep Xcode, source and caches unchanged where possible.
import json
import os
import signal
import subprocess
import sys
import time

for block in (512, 1024, 4096, 16384, 32768, 65536):
    r, w = os.pipe()
    os.set_blocking(w, False)
    total = 0
    try:
        while True:
            total += os.write(w, b'x' * block)
    except BlockingIOError:
        print('write block:', block, 'accepted bytes:', total)
    finally:
        os.close(r)
        os.close(w)

clang = subprocess.check_output(['xcrun', '--find', 'clang'], text=True).strip()
sdk = subprocess.check_output(
    ['xcrun', '--sdk', 'macosx', '--show-sdk-path'], text=True).strip()
argv = [clang, '-v', '-E', '-dM', '-arch', 'arm64',
        '-isysroot', sdk, '-x', 'c', '-c', '/dev/null']
t = time.monotonic()
result = subprocess.run(argv, capture_output=True, timeout=10)
print('concurrent:', result.returncode, round(time.monotonic() - t, 4),
      'stdout bytes:', len(result.stdout), 'stderr bytes:', len(result.stderr))

worker = (
    'import subprocess,json,sys; '
    'p=subprocess.Popen(json.loads(sys.argv[1]),'
    'stdout=subprocess.PIPE,stderr=subprocess.PIPE); '
    'out=p.stdout.read();err=p.stderr.read();p.wait();'
    'print(p.returncode,len(out),len(err))'
)
p = subprocess.Popen([sys.executable, '-c', worker, json.dumps(argv)],
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                     start_new_session=True)
t = time.monotonic()
try:
    out, err = p.communicate(timeout=5)
    print('sequential:', p.returncode, round(time.monotonic() - t, 4),
          out.decode().strip())
except subprocess.TimeoutExpired:
    os.killpg(p.pid, signal.SIGTERM)  # Only this disposable diagnostic group.
    p.communicate(timeout=5)
    print('sequential: timeout after 5 seconds')

The compiler command operates on /dev/null. Successful controls produced 15,789 stdout bytes and 4,829 stderr bytes. Independent C/Objective-C/C++ concurrent controls and a Swift DispatchIO control also succeeded.

What is the expected behavior?

Desktop tool runtimes and stdio connections should have bounded lifecycles/resource use. Prolonged desktop use should not exhaust a global pipe-buffer resource and stall unrelated developer tools. The app should release unused runtimes/descriptors or reuse them as appropriate.

Additional information

During the failure, sampled clang stacks ended in:

clang::driver::Command::Print
llvm::raw_ostream::write
llvm::raw_fd_ostream::write_impl
write

SWBBuildService's sampled main thread was idle in its run loop. Clang completed promptly when both streams were drained concurrently.

The leading explanation is global pipe-buffer pressure exposing a sequential-output-collection deadlock in the build tool:

  • Apple's XNU pipe implementation gates pipe-buffer growth on amountpipekva < maxpipekva. Relevant memory-limit sysctls were unavailable on this production kernel, so buffer-budget exhaustion is inferred from capacity probes and recovery, not directly measured.
  • Public SwiftBuild release/6.3 Process.swift collects stdout then stderr sequentially; main collects them concurrently. This explains a matching mechanism; the installed Xcode binary was not proven to correspond exactly to that release branch.

Related: #35582 already discusses retained CUA/MCP workers and global pipe-pool pressure. This report adds a specific Xcode compiler-discovery failure, measured pipe capacity, a project-independent compiler reproduction, and quantified before/after recovery. It should not be assumed to establish the same automation-specific retention path.

Important limitations:

  • Restart coincided with app bundle build 12404 changing to 12553. Restart-only and update effects cannot be separated; this does not prove the newer build fixes a particular leak.
  • The after-restart resource counts and compiler controls were independently measured. Successful full application build is user-reported; no successful build log was collected.
  • No growth series or controlled count of expected persistent chats was collected. The exact retention/cleanup owner remains unknown.
  • Other intervening user actions were not independently monitored.

Please investigate lifecycle/pooling of per-chat CUA/REPL and stdio MCP runtimes and the global pipe-resource impact during extended desktop use.

Privacy: this report contains only product versions, aggregate measurements, symbolic stack frames and a generic reproduction. It includes no names, usernames, email addresses, user paths, project identity/source, machine identifiers, process/chat/session IDs, location, screenshots, raw logs, credentials or billing details. No attachments or session uploads accompany this issue.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    mcpIssues related to the use of model context protocol (MCP) servers
    on Oct 5, 2026
  2. github-actions commented on Oct 5, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingcomputer-usemcpIssues related to the use of model context protocol (MCP) serversperformance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions