Closed morozov closed 2 years ago
UPD: it doesn't look related to the exit code. The same issue is reproducible without the exit code being PID:
<?php
$pid = pcntl_fork();
if ($pid === -1) {
echo 'Failed to create child process', PHP_EOL;
} elseif ($pid !== 0) {
echo 'Waiting for child PID ', $pid, PHP_EOL;
$result = pcntl_waitpid($pid, $status);
echo 'Received ', $result, PHP_EOL;
} else {
echo 'In child', PHP_EOL;
}
Produces:
$ php -v
PHP 8.0.14 (cli) (built: Dec 16 2021 11:20:34) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.14, Copyright (c) Zend Technologies
with Zend OPcache v8.0.14, Copyright (c), by Zend Technologies
with Xdebug v3.1.2, Copyright (c) 2002-2021, by Derick Rethans
$ php test.php
Waiting for child PID 99167
In child
Received 99167
$ php -v
PHP 8.1.1 (cli) (built: Dec 15 2021 09:54:28) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
with Zend OPcache v8.1.1, Copyright (c), by Zend Technologies
with Xdebug v3.1.1, Copyright (c) 2002-2021, by Derick Rethans
$ php test.php
Waiting for child PID 99176
In child
^C⏎ // never exits
Note that regardless of the issue, it's not necessary to use PID as the child exit code. According to the documentation,
pcntl_waitpid()
returns the process ID of the child which exited [...]
Only got an 8.1.0 here, but your sample code works fine for me and there isn't anything related in the 8.1.1 changelog.
$ php -v
PHP 8.1.0 (cli) (built: Dec 17 2021 08:56:50) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.0, Copyright (c) Zend Technologies
$ php temp.php
Waiting for child PID 18155
In child
Received 18155
PHPCS itself runs fine with the parallel setting for me as well.
I'd need more people to test this out and see if there is a generic problem here.
It must be related to macOS or PHP packaged by Brew. I cannot reproduce the issue in Docker either:
$ docker run -it php:8.1-cli bash
root@d6f3a4104add:/# docker-php-ext-install pcntl
root@d6f3a4104add:/# cat > test.php
<?php
$pid = pcntl_fork();
if ($pid === -1) {
echo 'Failed to create child process', PHP_EOL;
} elseif ($pid !== 0) {
echo 'Waiting for child PID ', $pid, PHP_EOL;
$result = pcntl_waitpid($pid, $status);
echo 'Received ', $result, PHP_EOL;
} else {
echo 'In child', PHP_EOL;
}
root@d6f3a4104add:/# php -v
PHP 8.1.1 (cli) (built: Dec 18 2021 00:28:00) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.1, Copyright (c) Zend Technologies
root@d6f3a4104add:/# php test.php
Waiting for child PID 2518
In child
Received 2518
@gsherwood please feel free to close as there's doubtfully something can be fixed in PHP_CodeSniffer itself.
Closing for now
Alright, the issue was caused by https://github.com/grpc/grpc/issues/20250. Once I disabled the grpc
extension, the issue disappeared.
Nice detective work @morozov !
Describe the bug If
phpcs
is run on PHP 8.1 with parallel processing enabled, the process never ends.Custom ruleset N/A
To reproduce Run
phpcs --parallel=2
Expected behavior PHP_CodeSniffer exits as soon as all files have been checked.
Versions (please complete the following information):
Additional context Quick debugging shows that although the child process exits with the exit code equal to its PID,
pcntl_waitpid()
keeps being executed in an infinite loop returning0
. https://github.com/squizlabs/PHP_CodeSniffer/blob/7eef328f4703620a6e7ebecb66b5fab9ca5015e3/src/Runner.php#L723-L724 When the same build runs on PHP 8.0,pcntl_waitpid
returns the value of the child PID as soon as it exits.According to the PHP documentation,
Using PID as the exit code seems to be a violation of the API and may be the root cause. https://github.com/squizlabs/PHP_CodeSniffer/blob/7eef328f4703620a6e7ebecb66b5fab9ca5015e3/src/Runner.php#L539