php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78225 Preloading Laravel results in a segfault
Submitted: 2019-06-28 09:51 UTC Modified: 2019-12-04 09:06 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: brent at spatie dot be Assigned: nikic (profile)
Status: Closed Package: opcache
PHP Version: 7.4.0alpha2 OS: macOS Mojave
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: brent at spatie dot be
New email:
PHP Version: OS:

 

 [2019-06-28 09:51 UTC] brent at spatie dot be
Description:
------------
I'm trying to preload Laravel. I've compiled php-7.4.0alpha2 using the following configure command:

```
./configure \
    OPENSSL_CFLAGS=-I/usr/local/opt/openssl/include \
    OPENSSL_LIBS="-L/usr/local/opt/openssl -lssl -lcrypto" \
    '--prefix=/Users/brent/dev/php/build/php-74-alpha2' \
    '--with-config-file-path=/Users/brent/dev/php/build/php-74-alpha2/etc' \
    '--with-config-file-scan-dir=/Users/brent/dev/php/build/php-74-alpha2/etc/conf.d' \
    '--enable-bcmath' \
    '--enable-calendar' \
    '--enable-dba' \
    '--enable-exif' \
    '--enable-fpm' \
    '--enable-mysqlnd' \
    '--enable-pcntl' \
    '--with-curl=/usr/local/opt/curl-openssl' \
    '--with-iconv=/Library/Developer/CommandLineTools/usr' \
    '--with-layout=GNU' \
    '--with-mysql-sock=/tmp/mysql.sock' \
    '--with-mysqli=mysqlnd' \
    '--with-openssl=shared' \
    '--with-openssl-dir=/usr/local/opt/openssl' \
    '--with-password-argon2=/usr/local/opt/argon2' \
    '--with-pdo-mysql=mysqlnd' \
    '--with-pdo-sqlite=/usr/local/opt/sqlite' \
    '--with-sodium=/usr/local/opt/libsodium' \
    '--with-sqlite3=/usr/local/opt/sqlite' \
```

The code to try it out can be found here: https://github.com/brendt/laravel-preload

This is the preload script: https://github.com/brendt/laravel-preload/blob/master/preload.php

After all files were preloaded, php-fpm crashes with the following error:

```
[1]    61893 segmentation fault  ./php-fpm --nodaemonize
```


Patches

did_you_try_adding_facades_prefix (last revision 2019-07-02 11:57 UTC by facades at laravel dot com)
deleting_laravel_solves_all_problems (last revision 2019-06-28 09:57 UTC by taylorotwell at laravel dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-06-28 16:23 UTC] ramsey@php.net
Is there a way to delete a patch submitted to a bug report? The submitted joke is unhelpful, rude, and has no place in the PHP bug tracker. Take your jokes to Twitter.
 [2019-07-01 08:13 UTC] beberlei@php.net
All examples Dmitry showed used opcache_compile_file instead of require. Can you try that?
 [2019-07-01 08:23 UTC] brent at spatie dot be
I added a version using opcache_compile:  https://github.com/brendt/laravel-preload/tree/opcache_compile ; it also results in a segfault.

The reason I wanted to use include or require is that it opcache_compile seemed to result in lots of unlinked classes. My guess was this it wouldn't resolve the class dependencies since the docs explicitly state that it won't execute the file.
 [2019-07-02 11:57 UTC] facades at laravel dot com
The following patch has been added/updated:

Patch Name: did_you_try_adding_facades_prefix
Revision:   1562068636
URL:        https://bugs.php.net/patch-display.php?bug=78225&patch=did_you_try_adding_facades_prefix&revision=1562068636
 [2019-07-02 12:48 UTC] brent at spatie dot be
-Summary: Preloading Laravel results in a segfault +Summary: brent@spatie.be
 [2019-07-02 12:48 UTC] brent at spatie dot be
I'm not sure whether the patch about facades was a troll or not, but it gave me a debug idea. It turns out the segfault only happens when trying to preload one of these classes:

- \Illuminate\Log\LogManager (https://github.com/laravel/framework/blob/5.8/src/Illuminate/Log/LogManager.php)
- \Illuminate\Http\Testing\File (https://github.com/laravel/framework/blob/5.8/src/Illuminate/Http/Testing/File.php)
- \Illuminate\Http\UploadedFile (https://github.com/laravel/framework/blob/5.8/src/Illuminate/Http/UploadedFile.php)
- \Illuminate\Support\Carbon (https://github.com/laravel/framework/blob/5.8/src/Illuminate/Support/Carbon.php)

I've also updated my example project: https://github.com/brendt/laravel-preload/commit/fa8e8b253ebd771f99c41554ed44b80197a23ba7
 [2019-07-02 12:49 UTC] brent at spatie dot be
-Summary: brent@spatie.be +Summary: Preloading Laravel results in a segfault
 [2019-07-02 12:49 UTC] brent at spatie dot be
Edit because of autofiller changing the summary
 [2019-07-03 11:45 UTC] nikic@php.net
I can't reproduce this crash on current 7.4 head.
 [2019-07-03 12:07 UTC] nikic@php.net
I've pushed some improved diagnostics for the unlinked class messages. You'll now see something like:

Warning: Can't preload unlinked class Illuminate\Http\Exceptions\PostTooLargeException: Unknown parent Symfony\Component\HttpKernel\Exception\HttpException in /home/nikic/laravel-preload/vendor/laravel/framework/src/Illuminate/Http/Exceptions/PostTooLargeException.php on line 8

Which should make it clear that the reason why you're not seeing much preloading is that you are only preloading Laravel, without its Symfony component dependencies.
 [2019-07-03 12:51 UTC] brent at spatie dot be
Thanks Nikita, the improved logging helps indeed.

Could you tell me what the correct approach would be in this case?

```
Can't preload unlinked class Ramsey\Uuid\Exception\UnsupportedOperationException: Parent with unresolved property types RuntimeException in
```

It turns out that this specific class extends `\RuntimeException` like so:


```
class UnsupportedOperationException extends \RuntimeException
```

How would you go about preloading built-in classes? Shouldn't this happen automatically?
 [2019-07-03 13:24 UTC] nikic@php.net
@brent: That one is likely a bug on our side, I'll take a look.
 [2019-07-04 10:44 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2019-07-04 10:44 UTC] nikic@php.net
I've landed a few more fixes and improvements. Preloading the whole vendor/ directory now works without crashing. There are still some warnings, but they mostly look legitimate (classes that are missing -- possibly optional deps?)

I'm closing this issue, please reopen or open a new one if you run into further problems.
 [2019-12-01 16:30 UTC] whois at itwrx dot org
@nikic@php.net
any chance you could share the code you used to preload the laravel vendor directory successfully? I've tried with brent's code (both compile and require versions)and php 7.4.0-2 (arch package) with laravel 6 and it's still seg faulting. Interestingly, I think the compile version loaded more files before it crashed. I've tried creating a simpler/more manual preload file, but loading dependencies and debugging is proving difficult for me.

Maybe this is naive, but it would be really nice if the php.ini config for preloading allowed the option to set an array of directories and php would preload all php files in those directories and any class dependencies, as an alternative to the preload script method.

thanks in advance.

p.s. here is the stack trace of the seg fault in case it is useful:

systemd[1]: php-fpm.service: Main process exited, code=dumped, status=11/SEGV
systemd[1]: php-fpm.service: Failed with result 'core-dump'.
audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj==unconfined msg='unit=php-fpm comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? >
systemd-coredump[187609]: Process 187591 (php-fpm) of user 0 dumped core.
                                                  
Stack trace of thread 187591:
   #0  0x0000645214e54ca0 _dl_close_worker (ld-linux-x86-64.so.2)
   #1  0x0000645214e55be2 _dl_close (ld-linux-x86-64.so.2)
   #2  0x00006452144c9d79 _dl_catch_exception (libc.so.6)
   #3  0x00006452144c9e13 _dl_catch_error (libc.so.6)
   #4  0x0000645214c29ab9 n/a (libdl.so.2)
   #5  0x0000645214c29468 dlclose (libdl.so.2)
   #6  0x00000163a11a1d5d n/a (php-fpm)
   #7  0x00000163a119b8dd n/a (php-fpm)
   #8  0x00000163a11ad4ca zend_hash_graceful_reverse_destroy (php-fpm)
   #9  0x00000163a119c7f6 n/a (php-fpm)
   #10 0x00000163a113cb4d php_module_shutdown (php-fpm)
   #11 0x00000163a122f17a n/a (php-fpm)
   #12 0x00000163a12277ad n/a (php-fpm)
   #13 0x00000163a122fe56 n/a (php-fpm)
   #14 0x00000163a1230afb n/a (php-fpm)
   #15 0x00000163a12272b5 n/a (php-fpm)
   #16 0x00000163a122c67b n/a (php-fpm)
   #17 0x00000163a1226b68 n/a (php-fpm)
   #18 0x00000163a0f53825 n/a (php-fpm)
   #19 0x00006452143b7153 __libc_start_main (libc.so.6)
   #20 0x00000163a0f5531e _start (php-fpm)
 [2019-12-04 09:06 UTC] nikic@php.net
No idea what I did for the full vendor directory (trying that gives me too many fatal errors due to legitimately wrong files in tests etc), but I just tried brent's code again just now and that seems to work.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 17:01:58 2024 UTC