26

PHP :: Bug #78918 :: Segfault with preloading Laravel

 4 years ago
source link: https://bugs.php.net/bug.php?id=78918
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

History

AllCommentsChangesGit/SVN commitsRelated reports
[2019-12-09 09:00 UTC] [email protected]
-Status: Open +Status: Verified
[2019-12-09 09:00 UTC] [email protected]
At the least there is an assertion failure during initial preloading:

php: /home/nikic/php-7.4/Zend/zend_hash.c:1019: _zend_hash_index_add_or_update_i: Assertion `(flag & (1<<3)) == 0' failed.
Aborted

#4  0x0000555555d9aaad in _zend_hash_index_add_or_update_i (ht=0x7fffeab4cd50 <accel_globals+368>, 
    h=17592143058440, pData=0x7fffffffcf30, flag=10) at /home/nikic/php-7.4/Zend/zend_hash.c:1019
#5  0x0000555555d9ad77 in zend_hash_index_add_new (ht=0x7fffeab4cd50 <accel_globals+368>, 
    h=17592143058440, pData=0x7fffffffcf30) at /home/nikic/php-7.4/Zend/zend_hash.c:1068
#6  0x00007fffea8acfff in zend_hash_index_add_new_ptr (ht=0x7fffeab4cd50 <accel_globals+368>, 
    h=17592143058440, pData=0x7fffe360fbe8) at /home/nikic/php-7.4/Zend/zend_hash.h:746
#7  0x00007fffea8ade22 in _zend_shared_memdup (source=0x7fffeb80b040, size=456, arena=0 '\000', 
    get_xlat=0 '\000', set_xlat=1 '\001', free_source=0 '\000')
    at /home/nikic/php-7.4/ext/opcache/zend_shared_alloc.c:387
#8  0x00007fffea8adf67 in zend_shared_memdup_put (source=0x7fffeb80b040, size=456)
    at /home/nikic/php-7.4/ext/opcache/zend_shared_alloc.c:417
#9  0x00007fffea8958d6 in zend_persist_class_entry (zv=0x7fffe3132de0)
    at /home/nikic/php-7.4/ext/opcache/zend_persist.c:708
#10 0x00007fffea898de1 in zend_accel_persist_class_table (class_table=0x7fffe312f4a0)
    at /home/nikic/php-7.4/ext/opcache/zend_persist.c:1032
#11 0x00007fffea8990f9 in zend_accel_script_persist (script=0x7fffe312f380, key=0x0, key_length=0, 
    for_shm=1) at /home/nikic/php-7.4/ext/opcache/zend_persist.c:1074
#12 0x00007fffea88b3cf in preload_script_in_shared_memory (new_persistent_script=0x7fffe2487a00)
    at /home/nikic/php-7.4/ext/opcache/ZendAccelerator.c:4092
#13 0x00007fffea88c986 in accel_preload (config=0x555556bdebe8 "preload.php")
    at /home/nikic/php-7.4/ext/opcache/ZendAccelerator.c:4413
#14 0x00007fffea88d334 in accel_finish_startup ()
    at /home/nikic/php-7.4/ext/opcache/ZendAccelerator.c:4644
#15 0x00007fffea887c6b in accel_post_startup ()
    at /home/nikic/php-7.4/ext/opcache/ZendAccelerator.c:3024
#16 0x0000555555d830ec in zend_post_startup () at /home/nikic/php-7.4/Zend/zend.c:1000
[2019-12-09 09:08 UTC] [email protected]
Okay, that one's easy to repro:

<?php
class A {}
class_alias(A::class, 'B');

This results in the class being in the class table twice, and we don't take that into account.
[2019-12-09 13:43 UTC] themohamedsaid at gmail dot com
After disabling all aliases and making sure class_alias is not used, I still get a segfault.

WARNING: [pool www] child 18450 exited on signal 11 (SIGSEGV - core dumped) after 1.191760 seconds from start
[2019-12-09 14:03 UTC] [email protected]
We've found some fundamental design problems in the preloading functionality today ...

The tl;dr is that you need to use opcache_compile_file() based preloading for now. Preloading based on require calls has a whole series of issues that may result in crashes.
[2019-12-09 17:05 UTC] themohamedsaid at gmail dot com
Unfortunately I keep getting a segfault even when switching to opcache_compile_file() and restarting php-fpm.

Wish I had more input to provide
[2019-12-10 10:40 UTC] fosron at gmail dot com
I've tested preloading Laravel too, and i'm getting "zend_mm_heap corrupted" with this script (https://github.com/brendt/laravel-preload/blob/master/preload.php) on a Docker container (both require and opcache_compile_file options don't work).
[2019-12-10 12:59 UTC] [email protected]
-Status: Verified +Status: Feedback
[2019-12-10 12:59 UTC] [email protected]
Support for class aliases has been added, and issues relating to classes with unresolved initializers fixed.

You will not get a fatal error if you try to preload a class with unresolved initializers under the "require" model (under the opcache_compile_file() model a graceful fallback is possible). However, opcache will try harder to make sure everything can be resolved.

I was not able to test preloading Laravel due to https://github.com/briannesbitt/Carbon/blob/298d9f0e8e369301b0ca647f3ce9c92b53ad3a82/src/Carbon/Traits/Date.php#L541-L556. This references constants that are not defined in the trait and are only available in the class using the trait. This will need to either be fixed, or the trait and it's dependencies skipped.
[2019-12-10 13:19 UTC] [email protected]
> You will not get a fatal error […]

That is supposed to be "You will now get a fatal error […]".
[2019-12-11 00:34 UTC] hopeseekr at gmail dot com
I would have guessed someone would have run Laravel's phpunit test suite while and after developing something as inner-touching as preloading.

Guess not! Probably didn't run Symonfy's tests either.
[2019-12-11 08:02 UTC] [email protected]
Additional failure case in class alias support:

interface I {}
class B implements I {}
class_alias('B', 'C');

update_parent_ce does not handle duplicate classes correctly.
[2019-12-16 09:05 UTC] brent at spatie dot be
Hi Nikita

I just used 7.4.1-RC1 to try out these changes. I didn't look too hard into the Carbon issue for now, and simply removed the constant references in the vendor folder, so that I'd be able to do my tests.

Unfortunately there's still a segfault, the same one:

0x00007fff7c4eb78e in ?? () from /usr/lib/system/libsystem_kernel.dylib

php-fpm is able to start and preload files, it's only after sending a request that the and when the Laravel kernel is triggered that the segfault happens. 

When opcache.preload is disabled in php.ini, things just work fine. Let me know if there's anything else I can test.
[2019-12-16 09:07 UTC] [email protected]
@brent: Can you please check whether it works with the built-in web server?
[2019-12-16 09:12 UTC] [email protected]
I should probably clarify that 7.4.1 will not contain all the preloading fixes. Some of them will only make 7.4.2 (current 7.4 branch).
[2019-12-16 12:02 UTC] brent at spatie dot be
Hi Nikita

Running it with the built-in server also gives a segfault:

[Preloader] Preloaded 192 classes
[Mon Dec 16 13:00:51 2019] PHP 7.4.1RC1 Development Server (http://localhost:8181) started
[Mon Dec 16 13:00:53 2019] [::1]:54280 Accepted
[Mon Dec 16 13:00:53 2019] [::1]:54281 Accepted
[1]    21300 segmentation fault  /Users/brent/dev/php/build/php-741-RC1/bin/php -S localhost:8181 -t public

I'll give the 7.4 branch a try later today or tomorrow though.
[2019-12-17 15:01 UTC] brent at spatie dot be
Hi Nikita

I've used PHP 7.4.1-dev now (commit https://github.com/php/php-src/commit/5ddcacac)

I'm still getting a segfault:

[1]    86293 segmentation fault  <php path>/bin/php -S localhost:8181 -t public

Using gdb I've got this (still no idea if this is useful at all for you)

0x00007fff7c4ec61a in ?? () from /usr/lib/system/libsystem_kernel.dylib

When I don't preload any classes, yet still provide a preload script, there's another segfault:

[1]    90260 segmentation fault  <php path>/bin/php -S localhost:8181 -t public

And finally, when opcache.preload and opcache.preload_user options are omitted in php.ini, the server works fine.
[2019-12-17 15:36 UTC] bugreports at gmail dot com
> [2019-12-17 15:01 UTC] brent at spatie dot be
> I've used PHP 7.4.1-dev now (commit https://github.com/php/php-src/commit/5ddcacac)

why?
7.4.1.dev is stone old when it comes to recent fixes
https://git.php.net/?p=php-src.git;a=shortlog;h=refs/heads/PHP-7.4
[2019-12-18 11:12 UTC] [email protected]
Unfortunately I'm not able to reproduce the segfault on Ubuntu. To make sure we're on the same page, here's what I do:

 * Clone the [email protected]:brendt/aggregate.stitcher.io.git repo
 * Run ~/php-7.4/sapi/cli/php composer.phar install
 * Patch vendor/nesbot/carbon/src/Carbon/Traits/Date.php to comment out the problematic $days static property.
 * Run the following command:
   ~/php-7.4/sapi/cli/php -c ~/php-7.4/php.ini -d opcache.preload=preload.php -S localhost:8000 -t public
 * Open localhost:8000 in the browser

Does this match what you're doing?

> Using gdb I've got this (still no idea if this is useful at all for you)
> 
> 0x00007fff7c4ec61a in ?? () from /usr/lib/system/libsystem_kernel.dylib

Is this the full backtrace? Do you get anything more when typing "backtrace" into gdb?
[2019-12-20 13:12 UTC] brent at spatie dot be
Hi Nikita

It's working now with the latest 7.4 build (7.4.2-dev). That's great! I'm getting some "already declared class" warnings still, but I guess that has to do with my preload script, stuff like ": Cannot declare interface Nette\DI\Config\IAdapter, because the name is already in use in
/Users/brent/dev/spatie/aggregate.stitcher.io/vendor/nette/di/src/compatibility.php"

I guess this one can be closed though, thank you for looking into this :)
[2019-12-20 13:16 UTC] brent at spatie dot be
Update: I've now also tested this with php-fpm, it also works.
[2019-12-28 19:15 UTC] [email protected]
-Status: Feedback +Status: Closed -Assigned To: +Assigned To: nikic
[2019-12-28 19:15 UTC] [email protected]
Thanks brent for checking. I'll close this issue -- let's open new bugs for any followup problems.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK