Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling include() on locked file on PHP 7.4 #36132

Closed
Prakson opened this issue Mar 18, 2020 · 12 comments
Closed

Calling include() on locked file on PHP 7.4 #36132

Prakson opened this issue Mar 18, 2020 · 12 comments

Comments

@Prakson
Copy link

Prakson commented Mar 18, 2020

Symfony version(s) affected: 4.4.5
Description
On PHP 7.4 (Windows) first booting of container (HttpKernel) causing the following PHP Notice:
Issue looks similar to #35242 but in different place in the code.

PS C:\Users\praszywa\Downloads\test> php test.php
PHP Notice:  include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php on line 566
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test.php:0
PHP   2. MyKernel->boot() C:\Users\praszywa\Downloads\test\test.php:6
PHP   3. MyKernel->initializeContainer() C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:136

Notice: include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php on line 566

Call Stack:
    0.0001     392400   1. {main}() C:\Users\praszywa\Downloads\test\test.php:0
    0.0054     723712   2. MyKernel->boot() C:\Users\praszywa\Downloads\test\test.php:6
    0.0054     727144   3. MyKernel->initializeContainer() C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:136

On PHP 7.3 (Windows) notice is not thrown.
For both versions of PHP error_reporting is set to E_ALL.

PHP Version:

PHP 7.4.4 (cli) (built: Mar 17 2020 13:49:13) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v2.9.3, Copyright (c) 2002-2020, by Derick Rethans

It's calling include on cachePath which is locked and not released.

How to reproduce
Create empty project with "symfony/symfony" ^4.4

{
    "name": "test/test",
    "autoload": {
        "psr-4": { "": "src/" }
    },
    "require": {
        "symfony/symfony": "4.4"
    }
}

Create dummy kernel

<?php

class MyKernel extends \Symfony\Component\HttpKernel\Kernel
{
    /**
     * @inheritDoc
     */
    public function registerBundles()
    {
        return [];
    }

    /**
     * @inheritDoc
     */
    public function registerContainerConfiguration(\Symfony\Component\Config\Loader\LoaderInterface $loader)
    {
        // TODO: Implement registerContainerConfiguration() method.
    }
}

Callboot kernel

<?php

require_once 'vendor/autoload.php';

$kernel = new MyKernel('dev', true);
$kernel->boot();

During first start (when cache doesn't exist) the following note will be visible:

PHP Notice:  include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php on line 566
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test.php:0
PHP   2. MyKernel->boot() C:\Users\praszywa\Downloads\test\test.php:6
PHP   3. MyKernel->initializeContainer() C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:136

Notice: include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php on line 566

Call Stack:
    0.0001     392400   1. {main}() C:\Users\praszywa\Downloads\test\test.php:0
    0.0054     723712   2. MyKernel->boot() C:\Users\praszywa\Downloads\test\test.php:6
    0.0054     727144   3. MyKernel->initializeContainer() C:\Users\praszywa\Downloads\test\vendor\symfony\symfony\src\Symfony\Component\HttpKernel\Kernel.php:136
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Mar 20, 2020

Since this varies by PHP version, isn't it a bug in PHP 7.4 instead of Symfony?

@michaljusiega
Copy link
Contributor

Add @ operator resolve temporarily this issue.

if (!\is_object($this->container = @include $cachePath)) {

This is due to a PHP error rather than Symfony.

@nicolas-grekas
Copy link
Member

would this work around it also?
if (is_readable($cachePath) && !\is_object($this->container = include $cachePath)) {

@michaljusiega
Copy link
Contributor

michaljusiega commented Mar 20, 2020

Yes, it works, but I can't cause a issue.

This occurs sporadically, I also confirm this error, so I added the operator @ to deal with the issue silently:>

@Prakson
Copy link
Author

Prakson commented Mar 20, 2020

would this work around it also?
if (is_readable($cachePath) && !\is_object($this->container = include $cachePath)) {

is_readable workaround doesn't work for me.
Silencing Notice using "@" works.

For me it happens only when "srcMyKernelxxxDebugContainer.php" doesn't exist.
I'm able to reproduce it every time using:
rm -r var/cache/dev/srcMyKernelDevDebugContainer.php && php test.php

Probably something connected with lock handling was changed in PHP 7.4 as you mentioned.

I did another try with simple script:


$cachePath = 'file.php';

$lock = fopen($cachePath, 'w');
chmod($cachePath, 0666 & ~umask());

$res = flock($lock, LOCK_EX | LOCK_NB, $wouldBlock);

include $cachePath;

PHP 7.3:

$ C:/Program\ Files/php-7.3.5-nts-Win32-VC15-x64/php.exe test2.php
OK

PHP 7.4

$ C:/Program\ Files/php-7.4.4-nts-Win32-VC15-x64/php.exe test2.php
PHP Notice:  include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\test2.php on line 10
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

Notice: include(): read of 4096 bytes failed with errno=13 Permission denied in C:\Users\praszywa\Downloads\test\test2.php on line 10

Call Stack:
    0.0002     393720   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

PHP Warning:  include(): Failed opening 'file.php' for inclusion (include_path='.;C:\php\pear') in C:\Users\praszywa\Downloads\test\test2.php on line 10
PHP Stack trace:
PHP   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

Warning: include(): Failed opening 'file.php' for inclusion (include_path='.;C:\php\pear') in C:\Users\praszywa\Downloads\test\test2.php on line 10

Call Stack:
    0.0002     393720   1. {main}() C:\Users\praszywa\Downloads\test\test2.php:0

OK

It looks like PHP 7.3 allows to include locked file, PHP 7.4 doesn't.

@nicolas-grekas
Copy link
Member

OK thanks, can you please open a PHP bug report? Maybe this will ring a bell to someone there?

@nicolas-grekas
Copy link
Member

Alternatively, we could have a lock file next to the one we include.

@Prakson
Copy link
Author

Prakson commented Mar 20, 2020

@cmb69
Copy link

cmb69 commented Mar 22, 2020

Well, not a PHP bug, see https://bugs.php.net/bug.php?id=79398#1584896555 (TL;DR include is subject to mandatory file locking on Windows as of PHP 7.4.0).

@nicolas-grekas
Copy link
Member

Thanks for the insights @cmb69!
@Prakson can you please check #36169?

@Prakson
Copy link
Author

Prakson commented Mar 23, 2020

It solved the issue.
Thanks!

nicolas-grekas added a commit that referenced this issue Mar 23, 2020
This PR was merged into the 4.4 branch.

Discussion
----------

[HttpKernel] fix locking for PHP 7.4+

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | #36132
| License       | MIT
| Doc PR        | -

As explained in https://bugs.php.net/79398

Commits
-------

f618b98 [HttpKernel] fix locking for PHP 7.4+
@Metallou-dev
Copy link

Issue still happens for symfony 5.0.5 BUT ONLY when using composer install|update.(happens always though)
It works when using cache:clear directly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants