Skip to content

Commit c3d48ef

Browse files
linesightclaude
andcommitted
macos: fix Mach rendezvous by injecting CFBundleIdentifier + CFProcessPath
CEF 130+ forms the MachPortRendezvousServer bootstrap service name as BaseBundleID() + ".MachPortRendezvousServer." + pid When the process has no app bundle (bare Python script), BaseBundleID() returns "" and the service name starts with "." — an invalid form that bootstrap_register rejects, causing all renderer subprocesses to crash at startup with "Unknown service name" (1102). Fix 1 (util_mac.mm): In MacInitialize() — which runs before CefInitialize() — inject CFBundleIdentifier="org.cefpython" into the main bundle's info dictionary when none exists. This gives BaseBundleID() a valid reverse-DNS prefix so the rendezvous server can register. Fix 2 (ci-macos.yml): Also create a minimal fake app bundle and set CFProcessPath before launching Python, so CFBundleGetMainBundle() picks up the bundle identifier at CoreFoundation init time (belt-and-suspenders for the CI runner's early initialization order). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 30b4a71 commit c3d48ef

2 files changed

Lines changed: 51 additions & 1 deletion

File tree

.github/workflows/ci-macos.yml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,33 @@ jobs:
121121
122122
- name: Run unit tests
123123
run: |
124-
PYTHONPATH="${{ github.workspace }}" python unittests/_test_runner.py
124+
# Create a minimal app bundle so Python has a CFBundleIdentifier.
125+
# CEF 130+ forms the MachPortRendezvousServer bootstrap service name
126+
# as BaseBundleID()+".MachPortRendezvousServer."+pid. Without a
127+
# bundle ID the name starts with "." which bootstrap_register rejects,
128+
# causing renderer subprocesses to crash. Setting CFProcessPath
129+
# before Python starts makes CFBundleGetMainBundle() return this
130+
# bundle, giving BaseBundleID() a valid value before CefInitialize().
131+
BUNDLE_DIR="${{ github.workspace }}/CEFPython.app"
132+
mkdir -p "$BUNDLE_DIR/Contents/MacOS"
133+
ln -sf "$(which python)" "$BUNDLE_DIR/Contents/MacOS/python"
134+
cat > "$BUNDLE_DIR/Contents/Info.plist" << 'PLIST'
135+
<?xml version="1.0" encoding="UTF-8"?>
136+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
137+
<plist version="1.0">
138+
<dict>
139+
<key>CFBundleIdentifier</key>
140+
<string>org.cefpython</string>
141+
<key>CFBundleName</key>
142+
<string>CEFPython</string>
143+
<key>CFBundleExecutable</key>
144+
<string>python</string>
145+
</dict>
146+
</plist>
147+
PLIST
148+
PYTHONPATH="${{ github.workspace }}" \
149+
CFProcessPath="$BUNDLE_DIR/Contents/MacOS/python" \
150+
python unittests/_test_runner.py
125151
126152
wheel:
127153
needs: test

src/client_handler/util_mac.mm

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,30 @@ void MacInitialize() {
7777
// OFF: it's causing a crash during shutdown release
7878
// g_autopool = [[NSAutoreleasePool alloc] init];
7979
[NSApplication sharedApplication];
80+
81+
// CEF 130+ builds the MachPortRendezvousServer bootstrap service name as
82+
// BaseBundleID() + ".MachPortRendezvousServer." + pid
83+
// When the process has no app bundle (e.g. a bare Python script),
84+
// BaseBundleID() returns "" and the name starts with ".", which
85+
// bootstrap_register rejects as invalid. All renderer subprocesses then
86+
// crash with "Unknown service name" (1102) on bootstrap_look_up.
87+
// Inject a synthetic CFBundleIdentifier before CefInitialize() so the
88+
// service name becomes a valid reverse-DNS label ("org.cefpython...").
89+
CFBundleRef mainBundle = CFBundleGetMainBundle();
90+
if (mainBundle) {
91+
CFStringRef bundleID = CFBundleGetIdentifier(mainBundle);
92+
if (!bundleID || CFStringGetLength(bundleID) == 0) {
93+
// CFBundleGetInfoDictionary returns the bundle's internal mutable
94+
// dictionary; casting to CFMutableDictionaryRef is safe here.
95+
CFMutableDictionaryRef infoDict =
96+
(CFMutableDictionaryRef)CFBundleGetInfoDictionary(mainBundle);
97+
if (infoDict) {
98+
CFDictionarySetValue(infoDict,
99+
CFSTR("CFBundleIdentifier"),
100+
CFSTR("org.cefpython"));
101+
}
102+
}
103+
}
80104
}
81105

82106
void MacShutdown() {

0 commit comments

Comments
 (0)