php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78512 Cannot make preload work
Submitted: 2019-09-08 13:58 UTC Modified: 2019-10-21 11:34 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:2 (100.0%)
From: nicolas dot grekas+php at gmail dot com Assigned: dmitry (profile)
Status: Closed Package: opcache
PHP Version: 7.4.0RC1 OS:
Private report: No CVE-ID: None
 [2019-09-08 13:58 UTC] nicolas dot grekas+php at gmail dot com
Description:
------------
This is a follow up from https://bugs.php.net/78175

Using https://github.com/nicolas-grekas/symfony/releases/download/php-bugs/preload-failures-78175.tar.bz2

I run
php -S localhost:8000 -t public/ -dopcache.preload=var/cache/prod/srcApp_KernelProdContainer.preload.php

Then in another console:
php info.php

Today, this fails with Class'ComposerAutoloaderInit0fc59465a08737274a67ea5841756d9a' not found.

When I call get_declared_classes(), the class is not listed.
But when I call opcache_get_status(), I see the class listed in preload_statistics.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-09-10 09:16 UTC] dmitry@php.net
-Status: Open +Status: Feedback
 [2019-09-10 09:16 UTC] dmitry@php.net
Not reproducible with PHP-7.4 GIT.

$ wget -qO- http://localhost:8000/
array(8) {
  ["debug"]=>
  int(0)
  ["info"]=>
  int(1)
  ["notice"]=>
  int(2)
  ["warning"]=>
  int(3)
  ["error"]=>
  int(4)
  ["critical"]=>
  int(5)
  ["alert"]=>
  int(6)
  ["emergency"]=>
  int(7)
}

$ wget -qO- http://localhost:8000/stats.php | grep -a ComposerAutoloaderInit0fc59465a08737274a67ea5841756d9a
    [235] => ComposerAutoloaderInit0fc59465a08737274a67ea5841756d9a
                    [82] => ComposerAutoloaderInit0fc59465a08737274a67ea5841756d9a
 [2019-09-10 16:07 UTC] nicolas dot grekas+php at gmail dot com
-Status: Feedback +Status: Open
 [2019-09-10 16:07 UTC] nicolas dot grekas+php at gmail dot com
I merged the needed code in Symfony so that it becomes easier to experiment with this.

Today, I get:
(514): Error Internal error: wrong size calculation: $PRELOAD$ start=0x00007fad51433380, end=0x00007fad51595870, real=0x00007fad515959e8

Here is my reproducer:

composer create-project symfony/skeleton:4.4.x@dev preload-test
cd preload-test
php -S localhost:8000 -t public/ -dopcache.preload=var/cache/prod/srcApp_KernelProdContainer.preload.php -dopcache.preload_user=root

FYI, I'm using docker pull devilbox/php-fpm-7.4 to get the code (built: Sep  9 2019 23:44:24).
 [2019-09-10 16:48 UTC] nikic@php.net
-Status: Open +Status: Verified
 [2019-09-10 16:48 UTC] nikic@php.net
I had to use -d opcache.preload=var/cache/dev/srcApp_KernelDevDebugContainer.preload.php.

php: /home/nikic/php-7.4/ext/opcache/ZendAccelerator.c:4293: accel_preload: Assertion `zend_gc_refcount(&(ht)->gc) == 1' failed.
 [2019-09-11 07:57 UTC] nikic@php.net
-Status: Verified +Status: Feedback
 [2019-09-11 07:57 UTC] nikic@php.net
After https://github.com/php/php-src/commit/0a24cd4e7c38d7565905152d4286ef0404d9d591 I get:

Warning: Can't preload already declared class Symfony\Bundle\FrameworkBundle\DependencyInjection\CompatibilityServiceSubscriberInterface in /home/nikic/repos/preload-test/vendor/symfony/framework-bundle/DependencyInjection/CompatibilityServiceSubscriberInterface.php on line 28

Warning: Can't preload already declared class Symfony\Contracts\EventDispatcher\EventDispatcherInterface in /home/nikic/repos/preload-test/vendor/symfony/event-dispatcher-contracts/EventDispatcherInterface.php on line 20

Warning: Can't preload unlinked class Symfony\Component\DependencyInjection\ExpressionLanguage: Unknown parent Symfony\Component\ExpressionLanguage\ExpressionLanguage in /home/nikic/repos/preload-test/vendor/symfony/dependency-injection/ExpressionLanguage.php on line 28

But otherwise it works.

Do you see any further issues?
 [2019-09-12 18:17 UTC] nicolas dot grekas+php at gmail dot com
built: Sep 11 2019 23:45:59 doesn't work yet for me:

This is gone: Error Internal error: wrong size calculation

php -S starts, but I still have Class 'ComposerAutoloaderInit...' not found when I access http://localhost:8000 afterwards.
When I call get_declared_classes(), the class is not listed.
But when I call opcache_get_status(), I see the class listed in preload_statistics.

Basically, the original issue description still applies to me sorry...
 [2019-09-13 07:58 UTC] nikic@php.net
-Status: Feedback +Status: Open
 [2019-09-13 07:58 UTC] nikic@php.net
I've tried with the prod env now to see if that makes a difference, but can't reproduce with that either. In that case I get a 404 page, but no errors.
 [2019-09-16 16:00 UTC] jhdxr@php.net
I confirm I can reproduce this issue with latest devilbox/php-fpm-7.4 docker image(588dad05d58f). 



however, I got another error when I tried with my dev environment (latest 7.4 branch, 6417c507ce511ecfc5d3f3818ffb01435f3086ee).

./configure --disable-all --disable-cgi --disable-phpdbg --enable-cli --enable-debug --enable-opcache 

./sapi/cli/php -S localhost:8000 -t ~/proj/php-src-tests/bug78512/preload-failures/public/ -dopcache.preload=~/proj/php-src-tests/bug78512/preload-failures/var/cache/prod/srcApp_KernelProdContainer.php

php: /home/jhdxr/proj/php-src/Zend/zend_string.c:264: zend_string_init_interned_permanent: Assertion `permanent' failed.



I'll try a full build later in my dev env to see if I can reproduce this issue.
 [2019-09-16 18:28 UTC] jhdxr@php.net
I think I find the key to reproduce this issue. You have to be root, and run with opcache.preload_user.

e.g. 
sudo ~/proj/php-src/sapi/cli/php -S localhost:8000 -t preload-failures/public/ -dopcache.preload=preload-failures/var/cache/prod/srcApp_KernelProdContainer.preload.php -dopcache.preload_user=jhdxr


Hope this helps.
 [2019-09-17 12:51 UTC] nicolas dot grekas+php at gmail dot com
I confirm that this error happens as root, and also that preloading works when running as non-root, thank you \o/
 [2019-10-07 10:24 UTC] hrvoje dot novosel at gmail dot com
I've been testing preload today on 7.4RC3 and also can't get it to work.
I don't know if its the same bug as this or unrelated, I'm testing with 2 simple scripts:

preload.php
<?php
class A{}

test.php
<?php
require_once('preload.php');
class B extends A {}
echo "ok";

when I run this without preload it works fine, when I enable preload
opcache.preload=/sambafs/preload.php
opcache.preload_user=apache
(I'm using php-fpm)
and try loading test.php I get
Fatal error: Uncaught Error: Class 'A' not found in ...

if I dump opcache stats I can see it there
[preload_statistics] => Array
        (
            [memory_consumption] => 3160
            [classes] => Array
                (
                    [0] => A
                )

            [scripts] => Array
                (
                    [0] => /sambafs/preload.php
                )

        )
but its not under get_declared_classes
 [2019-10-21 11:22 UTC] remi@php.net
-Status: Open +Status: Verified
 [2019-10-21 11:22 UTC] remi@php.net
Verified, with a trivial reporoducer

Normal user
$ echo '<?php class Foo {}' > Foo.php
$ php -d opcache.preload=Foo.php -r 'var_dump(class_exists("Foo"));'
bool(true)

Root user
# php -d opcache.preload_user=remi -d opcache.preload=Foo.php -r 'var_dump(class_exists("Foo"));'
bool(false)
 [2019-10-21 11:34 UTC] dmitry@php.net
-Assigned To: +Assigned To: dmitry
 [2019-10-21 11:53 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=05c5e5dfde91955263469daa2dd5afcbb5199d17
Log: Fixed bug #78512 (Cannot make preload work)
 [2019-10-21 11:53 UTC] dmitry@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Mon Dec 09 04:01:25 2019 UTC