Repository navigation
fix(next): do not start Chromium under an open-file limit it would run out of - #29377
lawrencecchen wants to merge 4 commits into
Conversation
… run out of Red: OpenFileLimit.chromiumShortfall() and CEFRuntime.loadLibrary's open-file gate are stubs here. Under a hard RLIMIT_NOFILE of 256 the app cannot raise its limit, and Chromium aborted the app 6 s after launch in its child launch (sandbox/mac/seatbelt_exec.cc:86-87, PFatal "SeatbeltExecClient: pipe failed", EMFILE; chaos fuzz row h, cmux21, 2026-10-31, symbolicated with the fork's cef-154.0.28-cmux.28 engine).
…n out of Under a hard RLIMIT_NOFILE below 1024 (a launch from a shell after `ulimit -n 256`, which sets both limits) the app cannot raise its limit, and Chromium aborted the whole app 6 s after launch: its child launch treats a failed pipe() as fatal (sandbox/mac/seatbelt_exec.cc:86-87, "SeatbeltExecClient: pipe failed", EMFILE). Chaos fuzz row h, cmux21, 2026-10-31, run h2-fd seed 2012, symbolicated with the fork's cef-154.0.28-cmux.28 engine. CEFRuntime.loadLibrary now refuses before the framework is mapped when the soft limit (after the app's raise) is below OpenFileLimit.chromiumFloor, so no Chromium thread runs. The failure is typed (CEFUnavailableReason.openFileLimit): Chromium tabs wait in place with a localized notice that names the limit and the way out (start from Finder or the Dock, or raise ulimit -n), and an explicit Chromium request is refused with the same text. It is logged once; a failed start is never tried again. Terminals, the daemon and WebKit pages are unchanged. Chrome's own model: it raises its limit at start and cannot run below its needs either; cmux refuses visibly instead of aborting.
…efused; CEFEngine reason mapping is pure and tested
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Default changesThis pull request changes 1 default at
Needs a review. It passes with an independent review receipt on this commit: a comment or review whose first line is Regenerate the snapshot with |
|
Found 1 test failure on Blacksmith runners: Failure
|
…nt page from a test root; floor comment gets the cmux21 numbers
|
Red proof (fleet step 511c65ab7749550617a4a903, red commit 3f4f750, cmux18-perf, compiled-at 632d52a): red as intended. Each new test that checks the refusal fails on the stubs:
Green at 632d52a (step 38b800283e82968fef401c4b, cmux22-perf): |
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
Summary
Under a hard
RLIMIT_NOFILEbelow 1024 (a launch from a shell afterulimit -n 256, which sets both limits), the app cannot raise its open-file limit, and Chromium aborted the whole app about 6 s after launch. Its child launch treats a failedpipe()as fatal:sandbox/mac/seatbelt_exec.cc:86-87,PFatal("SeatbeltExecClient: pipe failed"), EMFILE.Found by the restore/chaos fuzz (fuzz catalog row h, finding h1): run h2-fd seed 2012, cmux21, pid 23845, 2026-10-31 10:15:04Z, feat d1f0e63 Debug. Symbolicated with the fork's unstripped engine
cef-154.0.28-cmux.28-macos-arm64-debug.tar.xz(the engine UUID matches the crash report). The crashing thread:ChildProcessLauncherHelper::BeforeLaunchOnLauncherThread->sandbox::SeatbeltExecClient::SeatbeltExecClient()->sandbox::logging::PFatal->abort_report_np. The app's stderr showsFILE_ERROR_TOO_MANY_OPENEDin the same second. This is not memory pressure: the hog had ended 47 s earlier, and with the 15 GB hog the same build relaunched 82 times with 0 deaths.Change
CEFRuntime.loadLibraryrefuses to start Chromium, before the framework is mapped, when the soft limit after the app's own raise is belowOpenFileLimit.chromiumFloor(1024). So no Chromium thread runs.CEFUnavailableReason.openFileLimit). Chromium tabs wait in place (WebKit would open them signed out) with a localized notice that names the limit and the way out (start from Finder or the Dock, or raiseulimit -n). An explicit Chromium request gets the same text.agent.chromium):ChromiumPageHost.isAvailablenow reads the refused start, so new chats open in WebKit. A chat that asked before the refusal reopens in WebKit at once.openalways raises to at least 10240, so only a lowered hard limit is refused.Tests (red first)
3f4f7507fa3:OpenFileLimitTests(aHardLimitOf256KeepsChromiumFromStartingand 3 more),CEFOpenFileFloorTests.aHardLimitOf256RefusesTheLoad.CEFOpenFileFloorTests.theRefusalNamesTheLimitAndKeepsTabsOutOfWebKit,aRefusedStartIsUnavailableWithItsReason,PageWebViewChromiumTests.anAgentChatInChromiumFallsBackToWebKitWhenChromiumIsRefused.Observed / Not run
e41127457b18b29d053c48f0at632d52ad8e2: CmuxNext, app and cmux-tui ok.prepush-gate.py: no new violations,app_lines+0.localization_catalog.py check: no finding for the new key (21 locales).proof-step.pyrefuses Mac steps for this branch until it is on the Mac lane allow list (faster-2.md item 4); I asked the lead.ulimit -n 256with the fix (part of the queued floor measurement).No capture: the notice shows only under a hard open-file limit below 1024; a real capture comes with the floor measurement.
Changelog
Fixed: cmux no longer quits when it starts with a very low open-file limit; web pages show a notice that names the limit instead.
perf claim: none
Need help on this PR? Tag
@codesmith-botwith what you need.Summary by cubic
Fixes the app aborting about 6 seconds after launch when started under a hard open-file limit below 1024 — Chromium treated a failed
pipe()on its child-launch path as fatal. The app now refuses to start Chromium before its framework is loaded when the limit is too low, and shows a notice instead of crashing.openFileLimit): Chromium tabs wait in place with a localized notice that names the limit and the way out, instead of opening signed out in WebKit.Written for commit a40015e. Summary will update on new commits.