Skip to content

--parallel option fails if pcntl_waitpid returns non-managed process ID #1112

Open
@NanoSector

Description

@NanoSector

Describe the bug

The returned PID of pcntl_waitpid is not checked against the list of known PIDs in src/Runner.php. In our setup, this call always returns a PID with a value 1 lower than the lowest expected PID in the $childProcs list which causes phpcs and phpcbf to fail.

E.g. the $childProcs list contains [5125, 5126], but the function first returns 5124 and this causes the runner to crash with the following exception:

PHP Fatal error:  Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined array key 5124 in .../vendor/squizlabs/php_codesniffer/src/Runner.php on line 789 in .../vendor/squizlabs/php_codesniffer/src/Runner.php:624
Stack trace:
#0 .../vendor/squizlabs/php_codesniffer/src/Runner.php(789): PHP_CodeSniffer\Runner->handleErrors()
#1 .../vendor/squizlabs/php_codesniffer/src/Runner.php(560): PHP_CodeSniffer\Runner->processChildProcs()
#2 .../vendor/squizlabs/php_codesniffer/src/Runner.php(216): PHP_CodeSniffer\Runner->run()
#3 .../vendor/squizlabs/php_codesniffer/bin/phpcbf(14): PHP_CodeSniffer\Runner->runPHPCBF()
#4 .../vendor/bin/phpcbf(119): include('...')
#5 {main}
  thrown in .../vendor/squizlabs/php_codesniffer/src/Runner.php on line 624

Code sample

N/A, this bug happens in every project regardless of code snippets.

To reproduce

Steps to reproduce the behavior:

  1. Create two test PHP files and point phpcbf to them with the following command: bash -c 'bash --init-file <(echo "cd /home/vagrant/projects/my-project") -i -t -c "vendor/bin/phpcbf --parallel=8 -p test.php test2.php"'
  2. Notice the exception

Expected behavior

The parallel option works & phpcs only takes care of managed processes, even when invoked with constructs like these.

Versions (please complete the following information)

Operating System Ubuntu 22.04
PHP version 8.2
PHP_CodeSniffer version 3.13.0
Standard PSR12
Install type Composer (local)

Additional context

pcntl_waitpid already returns the lower value before the first call in pcntl_fork in Runner.php so this is very likely an external factor.

Patching Runner.php with the following code is sufficient to fix the issue, but I am not sure if this is the wanted solution:

        while (count($childProcs) > 0) {
            $pid = pcntl_waitpid(0, $status);
            if ($pid <= 0) {
                continue;
            }

change to

        while (count($childProcs) > 0) {
            $pid = pcntl_waitpid(0, $status);
            if ($pid <= 0 || !\array_key_exists($pid, $childProcs)) {
                continue;
            }

Please confirm

  • I have searched the issue list and am not opening a duplicate issue.
  • I have read the Contribution Guidelines and this is not a support question.
  • I confirm that this bug is a bug in PHP_CodeSniffer and not in one of the external standards.
  • I have verified the issue still exists in the master branch of PHP_CodeSniffer.

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