fix: skip Launch Services calls in forked children on macOS#1
Open
gthomas-strike wants to merge 1 commit intomasterfrom
Open
fix: skip Launch Services calls in forked children on macOS#1gthomas-strike wants to merge 1 commit intomasterfrom
gthomas-strike wants to merge 1 commit intomasterfrom
Conversation
CoreFoundation and Launch Services IPC calls are not fork-safe. On macOS Tahoe (26.x), calling these in a forked child process causes a SIGSEGV. This affects any application using gunicorn or similar pre-fork servers (e.g. Apache Airflow). Track the PID on first call to darwin_set_process_title(). In forked children, skip all Launch Services / CoreFoundation work and only call pthread_setname_np(), which is fork-safe. The argv clobbering path (handled by the caller) still functions correctly, so ps output continues to update in child processes.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SIGSEGV in forked child processes on macOS Tahoe (26.x)
Summary
setproctitle()crashes withSIGSEGVwhen called in a forked child process on macOS Tahoe (26.x). The crash occurs in the Darwin-specific Launch Services code path (darwin_set_process_name.c), where CoreFoundation and Launch Services IPC calls are made afterfork(). This breaks any application using a pre-fork server model (gunicorn, uWSGI, etc.).Affected versions
Background
The existing
checked_inguard inlaunch_services_set_process_title()(added in commit f5013d1 to fix dvarrazzo#111) protects the_LSApplicationCheckIncall from being invoked in a forked child. However, it does not protect:launch_services_init()itself, which callsdlopen(),CFBundleGetBundleWithIdentifier(), andCFBundleGetFunctionPointerForName()- all CoreFoundation callsLSGetCurrentApplicationASN()(line 124) - Launch Services IPCLSSetApplicationInformationItem()(line 130-134) - Launch Services IPCCoreFoundation is not fork-safe. On older macOS versions these calls happened to survive
fork(), but macOS Tahoe has tightened enforcement and they nowSIGSEGV.Crash trace
Captured via
faulthandler:The crash is at
gunicorn/arbiter.py:605, which is the_setproctitle()call in the child process immediately afterfork():Reproduction
Proposed fix
In
darwin_set_process_title(), track the PID on first call. In forked children (wheregetpid() != initial_pid), skip all Launch Services and CoreFoundation work. Only callpthread_setname_np(), which is fork-safe.This is placed in
darwin_set_process_title()rather thanlaunch_services_set_process_title()to guardlaunch_services_init()as well, which also makes CoreFoundation calls.What still works in forked children
PS_USE_CLOBBER_ARGVinspt_status.c): Unaffected. Theps_bufferandsave_argvpointers are valid in the child, sopsoutput still updates correctly.pthread_setname_np(): Fork-safe. Thread names are set correctly in child processes.What is skipped in forked children
LSSetApplicationInformationItemcall that updates the name in Activity Monitor. This is irrelevant for worker processes.Why PID-based detection over
pthread_atforkgetpid()syscall (cached by the kernel on macOS)atforkhandlers