homebrew-core: Apple segfaults when php-fpm scripts invoke gettext

brew gist-logs <formula> link OR brew config AND brew doctor output

https://gist.github.com/Saeven/ff8bc2e732a23622b1b5e784b83269c1

Verification

  • My “brew doctor output” says Your system is ready to brew. and am still able to reproduce my issue.
  • I ran brew update and am still able to reproduce my issue.
  • I have resolved all warnings from brew doctor and that did not fix my problem.
  • I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.

What were you trying to do (and why)?

PHP installs without issue, however, after installation any script that invokes gettext causes a crash. I’m unable to get a core for some reason, but I’ve isolated the issue to gettext.

Can confirm that it works on my old Intel Mac, but not on the M2 (mine) or that of a colleague (same CPU).

Create a script that contains:

<?php

echo gettext("hello");

Try to access the script via php-fpm and you get a bad gateway with a segfault in logs. Curiously, accessing via CLI produces the expected output.

What happened (include all command output)?

saeven@SaevenStudio ~ % sudo /opt/homebrew/opt/php/sbin/php-fpm --nodaemonize
Password: [24-Jul-2023 15:53:20] NOTICE: fpm is running, pid 19583 [24-Jul-2023 15:53:20] NOTICE: ready to handle connections [24-Jul-2023 15:53:30] WARNING: [pool www] child 19584 exited on signal 11 (SIGSEGV) after 9.763474 seconds from start [24-Jul-2023 15:53:30] NOTICE: [pool www] child 19587 started

What did you expect to happen?

No segfaults on access.

Step-by-step reproduction instructions (by running brew commands)

brew install php
brew install nginx

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 5
  • Comments: 83 (42 by maintainers)

Most upvoted comments

Following @dentarg advice, I’ve finally found a solution that works for Postgres even after a reboot. Although this still errors with echo gettext("hello");, so it’s only a solution for Postgres.

In /usr/local/etc/php/8.2/php-fpm.d/www.conf after the following:

; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp

Add an environment variable like this:

env['PGGSSENCMODE'] = disable

Then restart php. This will work even after a reboot.

Tested this working in php 8.2 and 7.4.

UPDATE: If you’re using laravel/valet the file should be /usr/local/etc/php/8.2/php-fpm.d/valet-fpm.conf as pointed here: https://github.com/laravel/valet/issues/1433#issuecomment-1710119112

@SMillerDev @Saeven

Laravel Valet is just a service wrapper which does manage nginx, php and dnsmasq services using homebrew services behind the scene to setup php environment. So it is actually all related with homebrew packages and services. (just php in this case).

So far we found out that running php-fpm via nginx and apache encounter segfault. And adding OBJC_DISABLE_INITIALIZE_FORK_SAFETY will fix it.

Why this happen?

Apple used to allow these process to run just logging warnings to the log. It was perfectly fine until Apple decided to kill it.

Did homebrew screw things up? No. Homebrew did nothing wrong. Did php screw things up? No. php did nothing wrong.

How about Linux? Does it kill php fork process? No.

Does adding OBJC_DISABLE_INITIALIZE_FORK_SAFETY to env is dangerous? Yes and No. Because even without adding this env parameters, problem has always been there. It keeps logging the warnings but also working fine.

Did your php code ever kill your OS using php-fpm? Your entire system? No. (Well, if you screw up with your php code really bad, it might be?)

So it was like php-fpm was running with OBJC_DISABLE_INITIALIZE_FORK_SAFETY ON all the time.

Only Apple who decided to kill it.

Linux: “this is fine. Keep going.” Windows: “we don’t have fork() process like Linux and macOS.”

Meanwhile php developers using macOS have tough time on this.

Until it gets fixed by php upstream, Homebrew adding this environment variable to its php startup script is really providing nice iced water for people in the living hell. I mean, it’s usually Mac people using Homebrew. Linux has their own distoro’s package manager. Using homebrew for linux is unlikely. Homebrew providing Mac only work-around to its package does sound like it should be. (But of course, upstream fix is ideal. This is just temporary. Please revert this fix after it gets fixed by upstream)

Observations:

Based on my experience, it is evident that the LC_ALL environment variable plays a significant role in this context. The output of the $ locale command suggests that an empty LC_ALL value might be a contributing factor to the issues observed:

LANG=""
LC_COLLATE="C"
LC_CTYPE="UTF-8"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

I got into the same problem yesterday on M2, Ventura 13.2. I wasn’t using any PHP framework, just plain old php-fpm and httpd, and my situation kinda matched your observation.

  • OBJC_DISABLE_INITIALIZE_FORK_SAFETY - solved some errors in log (forgot which) but still crashed when _("") is encountered
  • sudo - didn’t work
  • Upgrading to Ventura 13.5 - didn’t work
  • Adding putenv("LC_ALL=C"); to my PHP script before any _("") - worked like magic

I have removed OBJC_DISABLE_INITIALIZE_FORK_SAFETY from brew plist and the magic is still there.

Ref my previous post above - https://github.com/Homebrew/homebrew-core/issues/137431#issuecomment-1763366164

This worked for me: Add the following lines to your /usr/local/etc/php/<PHPVERSION>/php-fpm.d/www.conf Example /usr/local/etc/php/8.4/php-fpm.d/www.conf

;Signal 11 workaround
env['PGGSSENCMODE'] = disable
env['LC_ALL'] = C

And restart your effected PHP service, or test in running it directly: /usr/local/opt/php@8.4/sbin/php-fpm --nodaemonize

Needed this on all mine PHP versions, to make it work:

  • PHP 7.4
  • PHP 8.0
  • PHP 8.1
  • PHP 8.2
  • PHP 8.3
  • PHP 8.4

@Saeven @jonquihote @joshbyvelds

Related this https://github.com/Homebrew/homebrew-core/pull/137909#issuecomment-1659773001

Could you add following code to your /opt/homebrew/Cellar/php/8.2.8/homebrew.mxcl.php.plist and restart your php-fpm and see if it works (or not) please?

  • Before
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>
  • After
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>EnvironmentVariables</key>
        <dict>
            <key>OBJC_DISABLE_INITIALIZE_FORK_SAFETY</key>
            <string>YES</string>
        </dict>
        <key>KeepAlive</key>
        <true/>
        <key>Label</key>

I’m using Laravel Valet and tested like this:

  1. Make Valet Site and add index.php file
mkdir ~/Sites/testsite
vi ~/Sites/testsite/index.php

inside index.php file:

<?php

echo gettext("hello");
  1. Access to testsite.test which will serve index.php above -> This will throw 502 Bad Gateway

  2. Change /opt/homebrew/Cellar/php/8.2.8/homebrew.mxcl.php.plist to like above example and restart Laravel Valet (which restart php-fpm with new homebrew.mxcl.php.plist parameter)

  3. Access to testsite.test, now it outputs ‘hello’ without any problem.

Being Swiss, I might have a compromise regarding this issue and PR #137909:

I understand @carlocab does not want to change the suggested change for everyone. How about adding a file (e.g. homebrew.mxcl.php.plist-fork_safety) to the package and show a note after the installation, telling the user they can do

$ mv homebrew.mxcl.php.plist-fork_safety homebrew.mxcl.php.plist
$ brew services restart php

in order to work around the problem?

With that, no potentially dangerous setting would be forced upon any user. At the same time, users would immediately see that this workaround exists and could even apply it easily.

@askdkc Editing the the startup task with those parameters, so far, does eliminate the segfault being experienced. No Laravel here (Laminas!) - but in an nginx+php-fpm stack it allows the script to run. 🎉

For me on Apple M2 also adding putenv("LC_ALL=C"); at the beginning of the script helped. Thank you!

What makes the krb5 package a dependency to php? Kerberos support in the curl, MySQL and IMAP implementations

What alternatives exist?

Leaving PHP users with broken/incomplete cURL, MySQL and IMAP

Can we (someone) try an altered php build formula that excludes Kerberos as a proof of concept to diagnose that this issue lies in that dependency? And then maybe even try an older version of it as a second layer of testing?

Adding putenv(“LC_ALL=C”); to my PHP script before any _(“”) - worked like magic

If fixing an env var that gettext uses solves gettext from crashing upstream, then that suggests there’s a bug in gettext. What changed in gettext’s compilation/dependencies lately that’s causing it to crash when a simple env var is missing? Shouldn’t it fail a little more friendly?

@Saeven

This problem happens not only M1/2 but also Intel Mac too.

Could you change the issue title like “Segfaults when php-fpm scripts invoke gettext” ?

@nandi95

There are few points:

  1. Run brew services stop php
  2. Delete ~/Library/LaunchAgents/homebrew.mxcl.php.plist if it exists (This is inside of your home directory)
  3. Run brew upgrade
  4. Make sure you changed /opt/homebrew/Cellar/php/8.2.8_1/homebrew.mxcl.php.plist correctly (Or just copy and paste https://gist.github.com/askdkc/28480a0af1301993d92187920abec3bc)
  5. Run sudo brew services restart php (Make sure you use sudo)

If you are using Valet

Do 1 through 4 then

  1. Run rm -f .config/valet/valet82.sock
  2. Run valet install
  3. Run valet restart

Try these and see how it goes.

@askdkc

If you are using Valet with PostgreSQL like me, try this mattstauffer comment instruction: https://github.com/laravel/valet/issues/1433#issuecomment-1655883465 Perhaps the key point is Delete the php82 sock file (~/.config/valet/valet82.sock) and then valet install again See how it goes. Good luck!

I have tried the above, but it didn’t work. Later, when I was discouraged, I finally thought that this might be a system-related problem, so I tried to upgrade the system to Mac Ventura 13.5. Amazing, everything works now!

Currently OBJC_DISABLE_INITIALIZE_FORK_SAFETY is still set, I haven’t verified whether it is related to this setting (because it is normal after upgrading the system)

anyway thank you!

@askdkc

Yes, it make difference! Starting the the PHP service with sudo solve de problem even if the OBJC_DISABLE_INITIALIZE_FORK_SAFETY in not set in config. Tested on both Intel and M1 Macs with PHP configured in FPM mode (Server API: FPM/FastCGI).

If PHP is configured as Apache module (Server API: Apache 2.0 Handler) to solve the problem there is the need to start even httpd as root (sudo brew services start httpd).

PS: the _ gettext walkaround with putenv doesn’t work.

I am having the same issue as Saeven. Tried to reinstall php using the suggestion here and it still fails with the same error logs.

`[25-Jul-2023 15:34:36] NOTICE: fpm is running, pid 88426

[25-Jul-2023 15:34:36] NOTICE: ready to handle connections

[25-Jul-2023 15:35:51] WARNING: [pool www] child 88428 exited on signal 6 (SIGABRT) after 74.611026 seconds from start

[25-Jul-2023 15:35:51] NOTICE: [pool www] child 89954 started

[25-Jul-2023 15:36:23] WARNING: [pool www] child 88429 exited on signal 9 (SIGKILL) after 106.788182 seconds from start

[25-Jul-2023 15:36:23] NOTICE: [pool www] child 90238 started

[25-Jul-2023 15:36:28] WARNING: [pool www] child 88431 exited on signal 6 (SIGABRT) after 111.407527 seconds from start

[25-Jul-2023 15:36:28] NOTICE: [pool www] child 90309 started

[25-Jul-2023 15:41:24] WARNING: [pool www] child 88430 exited on signal 6 (SIGABRT) after 408.270930 seconds from start

[25-Jul-2023 15:41:24] NOTICE: [pool www] child 92347 started`