Skip to content

[HTTP-Kernel] Unreleased lock causes failed require() on KernelDebugContainer (Windows/PHP 7.4) #35242

Closed
@Jasonoro

Description

@Jasonoro

Symfony version(s) affected: 4.4.2

Description

The cache lock doesn't get released on PHP 7.4 on Windows, causing the require to fail.

Stack Trace:

PHP Warning:  Uncaught require(): read of 773 bytes failed with errno=13 Permission denied

C:\Users\<Username>\Documents\symfony-bug\locking-bug\vendor\symfony\http-kernel\Kernel.php:557
C:\Users\<Username>\Documents\symfony-bug\locking-bug\vendor\symfony\http-kernel\Kernel.php:557
C:\Users\<Username>\Documents\symfony-bug\locking-bug\vendor\symfony\http-kernel\Kernel.php:126
C:\Users\<Username>\Documents\symfony-bug\locking-bug\vendor\symfony\framework-bundle\Test\KernelTestCase.php:77
C:\Users\<Username>\Documents\symfony-bug\locking-bug\vendor\symfony\framework-bundle\Test\WebTestCase.php:47
C:\Users\<Username>\Documents\symfony-bug\locking-bug\tests\Controller\Admin\BlogControllerTest.php:41

PHP Version:

PHP 7.4.1 (cli) (built: Dec 17 2019 19:23:59) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v2.9.0, Copyright (c) 2002-2019, by Derick Rethans

Disabling Xdebug doesn't fix the problem.

How to reproduce

  1. Install the Symfony demo application
  2. Without any cache at all (Delete the whole cache folder) try to run PHPUnit vendor/bin/phpunit
  3. Running PHPUnit will fail with the above stack trace

Possible Solution

The logic in the code is that the unset($cache) just above the require calls the destructor and releases the lock. This however does not seem to happen in the latest version of PHP. Whether or not this is a bug in PHP itself I do not know. For now manually releasing the lock instead of relying on the destructor seems to be the best solution. As an example, changing the code to the following:

$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
flock($cache->lock, LOCK_UN);
unset($cache);
$this->container = require $cachePath;

fixes the problem.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions