Skip to content

Use plain fork() instead of __fork on macOS - #38

Merged
tonyfettes merged 2 commits into
mainfrom
use-plain-fork
Oct 26, 2026
Merged

tonyfettes merged 2 commits into
mainfrom
use-plain-fork

Conversation

@tonyfettes

@tonyfettes tonyfettes commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The macOS spawn path called the private __fork (weak-imported, returning ENOSYS if absent) to skip pthread_atfork handlers. That isn't needed:

  • Nothing we link registers pthread_atfork handlers. The MoonBit runtime (libmoonbitrun.o) statically links mimalloc, but as a non-overriding build: it only serves mi_malloc for MoonBit objects, does not replace malloc or register a malloc zone, and neither it nor the linked test binaries import pthread_atfork (checked with nm -u on moon 0.1.20261023). So the only handlers __fork skipped were libSystem's own, and those are what keep the child's libc state consistent (malloc zone locks taken around the fork, mach ports reset in the child).
  • The forked child only makes plain syscalls (sigaction, setsid, ioctl(TIOCSCTTY), dup2, chdir, execve, nanosleep) and never allocates (neither through malloc nor mimalloc), so plain fork() is sufficient.

We still have to fork rather than posix_spawn on macOS (XNU runs file actions before POSIX_SPAWN_SETSID, so the child can't acquire the pty as its controlling terminal); this only changes which fork is called. All unix platforms now share the same fork() path that Linux already used.

Testing

  • macOS (Darwin 25.6): moon test passed 26/26 in 13 consecutive runs, no hangs.
  • Linux is unchanged (it already used fork()).

__fork was used to skip pthread_atfork handlers, but nothing we link
registers any, and libSystem's own handlers are what keep the child's
libc state (malloc zone locks, mach ports) consistent. The child only
makes plain syscalls, so plain fork() is sufficient and drops a private,
weak-imported symbol.
@tonyfettes
tonyfettes merged commit d1e95cd into main Oct 26, 2026
4 checks passed
@tonyfettes
tonyfettes deleted the use-plain-fork branch October 26, 2026 07:59
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.

1 participant