Skip to content

Commit e69f40a

Browse files
linesightclaude
andcommitted
macos: inject CFBundleIdentifier in subprocess before MachPortRendezvous lookup
CEF 130+ builds the MachPortRendezvousClient service name as: CFBundleIdentifier + ".MachPortRendezvousServer." + parent_pid The browser process injects CFBundleIdentifier = "org.cefpython" via MacInitialize() in util_mac.mm before CefInitialize(), so it registers: "org.cefpython.MachPortRendezvousServer.<pid>" The subprocess binary is a flat binary (not in an app bundle), so CFBundleGetMainBundle() returns no CFBundleIdentifier and the client looks up ".MachPortRendezvousServer.<parent_pid>" — a name starting with "." that bootstrap_look_up can never find (BOOTSTRAP_UNKNOWN_SERVICE 1102). This caused every spawned subprocess to terminate immediately with "No rendezvous client, terminating process (parent died?)". Fix: add main_mac.mm (compiled only on Apple) which injects the same "org.cefpython" bundle identifier into the subprocess's main bundle dict before CefExecuteProcess runs, matching what the parent registered. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent eadf73a commit e69f40a

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

src/subprocess/main.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
3030

3131
int main(int argc, char **argv)
3232
{
33+
#if defined(OS_MAC)
34+
// CEF 130+: MachPortRendezvousClientMac builds the service name as
35+
// CFBundleIdentifier + ".MachPortRendezvousServer." + parent_pid
36+
// The browser process injects CFBundleIdentifier = "org.cefpython" in
37+
// MacInitialize() before CefInitialize(). This subprocess binary is a flat
38+
// binary (not an app bundle), so CFBundleGetMainBundle() returns no
39+
// CFBundleIdentifier, producing a lookup name starting with "." that never
40+
// matches the registered service. Call SubprocessMacInit() to inject the
41+
// same identifier so bootstrap_look_up finds the server.
42+
extern "C" void SubprocessMacInit();
43+
SubprocessMacInit();
44+
#endif
3345
#if defined(OS_LINUX)
3446
// Chrome 130+ passes --pseudonymization-salt-handle to directly-launched
3547
// (non-zygote) subprocesses, expecting GlobalDescriptors[key] to be

src/subprocess/main_mac.mm

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2025 CEF Python, see the Authors file.
2+
// All rights reserved. Licensed under BSD 3-clause license.
3+
// Project website: https://github.com/cztomczak/cefpython
4+
5+
#import <CoreFoundation/CoreFoundation.h>
6+
7+
// Called from main.cpp before CefExecuteProcess on macOS.
8+
//
9+
// CEF 130+ builds the MachPortRendezvousClient lookup name as:
10+
// CFBundleIdentifier + ".MachPortRendezvousServer." + parent_pid
11+
//
12+
// The parent (browser process) has CFBundleIdentifier = "org.cefpython"
13+
// injected in util_mac.mm / MacInitialize(). The subprocess is a flat
14+
// binary without an app bundle, so CFBundleGetMainBundle() returns no
15+
// CFBundleIdentifier and the lookup name starts with ".", which never
16+
// matches the registered service name. Inject the same identifier here
17+
// so both sides agree and bootstrap_look_up succeeds.
18+
extern "C" void SubprocessMacInit() {
19+
CFBundleRef mainBundle = CFBundleGetMainBundle();
20+
if (mainBundle) {
21+
CFStringRef bundleID = CFBundleGetIdentifier(mainBundle);
22+
if (!bundleID || CFStringGetLength(bundleID) == 0) {
23+
CFMutableDictionaryRef infoDict =
24+
(CFMutableDictionaryRef)CFBundleGetInfoDictionary(mainBundle);
25+
if (infoDict) {
26+
CFDictionarySetValue(infoDict,
27+
CFSTR("CFBundleIdentifier"),
28+
CFSTR("org.cefpython"));
29+
}
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)