Skip to content

Fix background process creation on macOS#15834

Open
jtainer wants to merge 1 commit into
libsdl-org:mainfrom
jtainer:main
Open

Fix background process creation on macOS#15834
jtainer wants to merge 1 commit into
libsdl-org:mainfrom
jtainer:main

Conversation

@jtainer

@jtainer jtainer commented Jun 16, 2026

Copy link
Copy Markdown
  • I confirm that I am the author of this code and release it to the SDL project under the Zlib license. This contribution does not contain code from other sources, including code generated by a Large Language Model ("AI").

This fixes an issue on macOS where the PID of a background child process is never stored by the main process.

Description

Currently on macOS, when creating a process with SDL_PROP_PROCESS_BACKGROUND_BOOLEAN=true, the PID returned by posix_spawnp() is never visible to the parent process, since it is stored in a different address space created by fork(). So, a PID of 0 is stored in in the parent process, and attempting to call KillProcess(child) actually sends the signal to the parent process. This issue did not occur on other posix systems since they used vfork() instead of fork(), allowing the child process to record the PID in the parent's address space directly.

To resolve this, the process created by fork() sends the PID returned by posix_spawnp() back to the parent process over a pipe. Additionally, I switched to using fork() instead of vfork() in all cases, for the sake of consistency and standard-compliance.

Existing Issue(s)

N/A

@slouken slouken added this to the 3.6.0 milestone Jun 16, 2026
@slouken slouken requested a review from icculus June 16, 2026 23:56
@icculus

icculus commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

I need to look at this PR more carefully when it isn't 5am here, but to be clear: this isn't a Mac-specific bug, this is a misuse of vfork() to assume you can alter the parent process's memory.

The docs on some systems say that the new child process shares the parent's memory, but also POSIX says that you can just implement vfork() as fork()--indeed, this is exactly what macOS 12.0 did--in which case our current vfork hack will never work.

The latest POSIX specs have outright removed vfork.

The Linux manpages suggest there are (Linux-specific) benefits to using it, but we should probably just nuke it from orbit as too unsafe to trust, and use a mechanism like this PR on all platforms.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants