Fix Illegal Instruction: 4 Error When Installing php74 via macports on macOS

crashmacportsPHPterminalxcode

I have an issue with php74 compiled by macports that is crashing with illegal instruction 4 when i run phpunit for unit testing my project.

uname -v
Darwin Kernel Version 20.3.0: Thu Jan 21 00:07:06 PST 2021; root:xnu-7195.81.3~1/RELEASE_X86_64

sudo port selfupdate
Password:
--->  Updating MacPorts base sources using rsync
MacPorts base version 2.6.4 installed,
MacPorts base version 2.6.4 downloaded.
--->  Updating the ports tree


I use this computer for website development with php74, apache 2.4 and mysql8.

This was working well and i was able to run unit tests on my project using phpunit 8.5.4

The other day the computer locked up and was un-responsive so I powered off and on again.

After that, the unit tests (phpunit) running php74 (7.4.15) command exits with illegal instruction 4.

Other php commands, executed either via apache, or from the CLI work ok, it just appears to be the phpunit commands that break php74.

i re-installed an earlier versions of php74, (7.4.14 & 7.4.13) and the compiler complained that MacOSX11.2 was missing. using the earlier version of php => same error.

i tried another version of phpunit (9.5.2) => same error.

i run the disk utility to scan drive errors, none found => same error

i tried copying the /opt/local/php74 from another mac to this computer => same error.

i have:
completely removed xcode.
removed macports and uninstalled all ports.
re-installed xcode 12.4
symbolically linked the 11.3 SDK to 11.2 ie:

ls -Al  /Library/Developer/CommandLineTools/SDKs
total 0
lrwxr-xr-x  1 root  wheel   14 24 Feb 11:08 MacOSX.sdk -> MacOSX11.3.sdk
drwxr-xr-x  8 root  wheel  256 24 Feb 11:09 MacOSX10.15.sdk
lrwxr-xr-x  1 root  wheel   55 24 Feb 14:49 MacOSX11.2.sdk -> /Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk
drwxr-xr-x  7 root  wheel  224 24 Feb 11:08 MacOSX11.3.sdk

this link removed the macports warning, not sure if it was correct, but it appears to work.

re-installed all ports

and the error remains.

./phpunit --group Jobs_model
PHPUnit 9.5.2 by Sebastian Bergmann and contributors.

Warning:       Your XML configuration validates against a deprecated schema.
Suggestion:    Migrate your XML configuration using "--migrate-configuration"!

zsh: illegal hardware instruction  ./phpunit --group Jobs_model

sudo port installed | grep -e php -e mysql -e apache
  apache2 @2.4.46_1+preforkmpm (active)
  mysql8 @8.0.23_0 (active)
  mysql8-server @8.0.23_0 (active)
  mysql_select @0.1.2_4 (active)
  php74 @7.4.15_0+libedit (active)
  php74-apache2handler @7.4.15_0 (active)
  php74-calendar @7.4.15_0 (active)
  php74-cgi @7.4.15_0 (active)
  php74-curl @7.4.15_0 (active)
  php74-exif @7.4.15_0 (active)
  php74-fpm @7.4.15_0 (active)
  php74-ftp @7.4.15_0 (active)
  php74-gd @7.4.15_0 (active)
  php74-geoip @1.1.1_0 (active)
  php74-gettext @7.4.15_0 (active)
  php74-gmagick @2.0.5RC1_0 (active)
  php74-iconv @7.4.15_0 (active)
  php74-igbinary @3.2.1_0 (active)
  php74-intl @7.4.15_0 (active)
  php74-ldap @7.4.15_0 (active)
  php74-mbstring @7.4.15_0 (active)
  php74-memcached @3.1.5_0 (active)
  php74-mysql @7.4.15_0+mysqlnd (active)
  php74-opcache @7.4.15_0 (active)
  php74-openssl @7.4.15_0 (active)
  php74-soap @7.4.15_0 (active)
  php74-sodium @7.4.15_0 (active)
  php74-xdebug @3.0.2_0 (active)
  php74-xmlrpc @7.4.15_0 (active)
  php74-zip @1.19.2_0 (active)
  php_select @1.0_0 (active)

my question is, what is recommended to fix this?

I really don't want to wipe the mac, but it is sort of moving in that direction.

here is an example stack trace from the error console. https://pastebin.com/td7Xi4EL

Best Answer

Here are the important parts:

Exception Codes:       KERN_PROTECTION_FAILURE at 0x00007ffeeccd3ff8

VM Regions Near 0x7ffeeccd3ff8:
    MALLOC_LARGE             7ff27e800000-7ff27f101000 [ 9220K] rw-/rwx SM=PRV  
--> STACK GUARD              7ffee94d4000-7ffeeccd4000 [ 56.0M] ---/rwx SM=NUL  stack guard for thread 0
    Stack                    7ffeeccd4000-7ffeed4d4000 [ 8192K] rw-/rwx SM=ALI  thread

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib          0x00007fff2035068f __commpage_gettimeofday_internal + 31
1   libsystem_c.dylib               0x00007fff20266b6d gettimeofday + 45
2   libsystem_c.dylib               0x00007fff20282584 time + 48
3   php                             0x000000010292db7c tsrm_realpath_r + 384
    [...]
503 xdebug.so                       0x000000010551e540 xdebug_execute_ex + 1121
504 php                             0x000000010295e495 ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER + 405
505 php                             0x0000000102942ae7 execute_ex + 35
506 xdebug.so                       0x000000010551e540 xdebug_execute_ex + 1121
507 php                             0x000000010295e495 ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER + 405
508 php                             0x0000000102942ae7 execute_ex + 35509 xdebug.so                         0x000000010551e540 xdebug_execute_ex + 1121
510 php                             0x000000010295e495 ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER + 405
511 php                             0x0000000102942ae7 execute_ex + 35

Notice that you're at exactly 512 (= 2^9) stack frames and the parent frames have been truncated. You're getting a KERN_PROTECTION_FAILURE at 0x7ffeeccd3ff8 because you've overflowed the maximum stack size and you're trying to write to a protected region (the illegal address is just above Stack in the STACK GUARD region, which was created expressly to catch situations like this).

This happened because there was a highly recursive function call chain and it simply exceeded the 512 frame (8192 KB) default stack limit (see ulimit -s). From the looks of the recursed frames (ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER() over and over), I'd guess that it's php code (either yours or the unit testing framework) which is recursing, rather than the C code of the interpreter itself.

If you aren't sure where the recursion is occurring, one temporary workaround would be to raise the stack limit of the php process using ulimit(1) and run your command again in the same Terminal window:

ulimit -s 65532
./phpunit --group Jobs_model

This will run your test with a 64 MB stack limit. Note that the kernel specifies a maximum upper stack limit of 64 MB:

#define DFLSSIZ         (8*1024*1024)           /* initial stack size limit */

#define MAXSSIZ         (64*1024*1024)          /* max stack size */

so if your recursion is way huge, you'll still run out of space. At that point, though, you would really want to find out what's recursing so much.