-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
RuntimeException: Undefined variable: childOutput in squizlabs/php_codesniffer/src/Runner.php on line 705 #2304
Comments
I can't replicate this (php 7.3, mac os), but it would mean that something pretty bad has gone wrong. If you are using a parallel value of 2, it means at least one of the two forks has exited but not written any data to the output file. I assume this means it died early, but I'm not sure why. It could be that the temp output file couldn't be written for some reason. Without adding debug information into the runner, I'm not really sure how to figure out where it is dying. But there are some things to try:
If you can try those things and post your findings, maybe something might show up. Alternatively, if you'd like to add some debug code, I'd start in $output .= ";\n?".'>';
echo "ABOUT TO WRITE TO $childOutFilename\n";
file_put_contents($childOutFilename, $output);
echo "ABOUT TO EXIT\n";
exit($pid); |
Thank you @gsherwood for your response. This is the output with $ ./vendor/bin/phpcs -v
Registering sniffs in the Tamtam coding standard standard... DONE (42 sniffs registered)
Creating file list... DONE (1 files in queue) I get the error in this line: PHP_CodeSniffer/src/Runner.php Lines 702 to 709 in ab6caa0
The existence of PHP_CodeSniffer/src/Runner.php Lines 679 to 685 in ab6caa0
adding and |
I had the same issue :( |
I figured it would, but I asked for more testing because it would be good to find out why your child processes are not outputting data. If they aren't producing output, it is quite likely that you are not seeing errors that are being generated. This is why I asked if you could do some test runs over a single file, then 2 identical files. You need to be sure that the results you are getting are still valid, or else you are just hiding a very serious error. |
I have the same error when a use --parallel value >1. |
@gsherwood You're right, this is more complicated. The child processes aren't outputting any data. It dies quietly on this line, and then continues the loop, therefore never reaching the code that outputs the file contents: https://github.com/squizlabs/PHP_CodeSniffer/blob/master/src/Runner.php#L454 |
More info: this function call successfully runs, but anything placed after this function call does not: https://github.com/squizlabs/PHP_CodeSniffer/blob/master/src/Files/LocalFile.php#L74 Adding logging to the Due to the absence of error/warning/notice output and the fact that the script seems to mysteriously die, this feels to me like a possible race condition, in which the thing that is causing the script to stop is the fatal itself. |
I have the same problem with php 7.3. One Project ist okey and another have the problem. I can it reproduce only on mac and on alpine is fine. |
I have the same issue on mac using
Downgrading back to v7.1.23 works correctly |
Getting these too in PHPStorm with CodeSniffer enabled since updating to 7.3 (brew). Don't have the parallel option set in my config, but maybe PHPStorm sets it.
|
Yep, crash in |
The only way I can get the error to happen is if the child processes run out of memory. Is it possible that the fatal error is being suppressed for anyone, and that the child processes are actually dying due to memory limits? |
PHP 7.3.1 and 7.3.2 My notes for what I tried in getting to the outcome below
➜ vipcs git:(fix/ruleset-test-improvements) ✗ vendor/bin/phpcs tests/RulesetTest.php -v
Registering sniffs in the VIP Coding Standards standard... DONE (227 sniffs registered)
Creating file list... DONE (1 files in queue)
PHP Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined variable: childOutput in /path/to/vendor/squizlabs/php_codesniffer/src/Runner.php on line 712 in /path/to/vendor/squizlabs/php_codesniffer/src/Runner.php:569
As above.
Duplicated RulsetTest.php and the command. Output as above. As expected, commenting out the
As above (though with different line numbers due to the additional debug code). I added my own debugging within When I added a debug inside of the At a guess, this does seem to suggest that when I did some more debugging earlier Runner::run(), at the When running with In terms of that file writing process, there's some output buffering - I could get some echos working just before the The was my output - note the inconsistent position of ob_start - perhaps there's some sort of race condition going on?:
Either way, with no processing getting past that output buffering, no child process temp files are even getting to the From the docs (my emphasis):
OutcomeTaking it in a different direction, I added an Here's my extra debug code (starting [here])( PHP_CodeSniffer/src/Runner.php Line 533 in a982ecd
$output .= ";\n?".'>';
echo 'About to write file ' . $childOutFilename . "\n";
file_put_contents($childOutFilename, $output);
//var_dump( file_get_contents( $childOutFilename ) );
exit($pid);
}//end if
}//end for
echo 'FINISHED LOOP' . "\n"; And my output: Batch: 0
Child process created. PID = 40174
Batch: 1
Child process created. PID = 40175
Batch: 2
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child4FQCyE
Child process created. PID = 40176
Batch: 3
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childedI8Ol
Child process created. PID = 40177
Batch: 4
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childE3LXir
Child process created. PID = 40178
FINISHED LOOP
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child6DuKPE
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childujhpCQ
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child4FQCyE exists. (That last "File ... exists" message is in In this case, the FINISHED LOOP was appearing, before all of the the With PHP 7.2, my output is: Batch: 0
Child process created. PID = 46277
Batch: 1
Child process created. PID = 46278
Batch: 2
Child process created. PID = 46279
Batch: 3
Child process created. PID = 46280
Batch: 4
Child process created. PID = 46281
FINISHED LOOP
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childr37H17
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childr37H17 exists.
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childRI5nsH
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childRI5nsH exists.
EAbout to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childjTwoSr
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childjTwoSr exists.
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childvQ8Fjk
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childvQ8Fjk exists.
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childe4qV6Z
File /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childe4qV6Z exists.
. 5 / 5 (100%) Which again suggests the same regarding initial file-writing, but it is in a different order, but more importantly, each file exists before it is processed. Both PHP 7.3 and 7.2 have been compiled with If I |
The way this is supposed to work means that The Given that the error here is So either the child died before it could write to the file, or the Debug code right before the |
Thank you for that explanation. It would be useful for future readers to have some of that added to DocBlocks / inline comments, for those of us who aren't familiar with child processes in PHP.
Yes. For brevity, I commented out the var_dump() and hadn't been including it by dumps here, but I thought that yes, the file was being written and I could retrieve the contents. However, I've just tried it again, and the results are different: For PHP 7.2, all looks good: PHP 7.2 outputBatch: 0
Child process created. PID = 3574
Batch: 1
Child process created. PID = 3575
Batch: 2
Child process created. PID = 3576
Batch: 3
Child process created. PID = 3577
Batch: 4
Child process created. PID = 3578
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childTt63fF
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childTt63fF
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childMqOLG4
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childMqOLG4
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childwA0158
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childwA0158
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childFU5kxL
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childFU5kxL
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
.About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childSgSQwZ
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childSgSQwZ
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
. 5 / 5 (100%) For PHP 7.3, it doesn't get to the var_dump call: PHP 7.3 outputBatch: 0
Child process created. PID = 12676
Batch: 1
Child process created. PID = 12677
Batch: 2
Child process created. PID = 12678
Batch: 3
Child process created. PID = 12679
Batch: 4
Child process created. PID = 12680
PHP Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined variable: childOutput in /Users/gary/code/vipcs/vendor/squizlabs/php_codesniffer/src/Runner.php on line 718 in /Users/gary/code/vipcs/vendor/squizlabs/php_codesniffer/src/Runner.php:575 There's a debug line after If I comment out the block of code from PHP 7.3 with output buffering disabledBatch: 0
Child process created. PID = 29038
Batch: 1
Child process created. PID = 29039
Batch: 2
About to call ob_start().
About to call ob_start().
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child5eVgKr
Child process created. PID = 29040
Batch: 3
About to call ob_start().
About to call ob_start().
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child5eVgKr
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child4wstxf
Child process created. PID = 29041
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child4wstxf
Batch: 4
About to call ob_start().
About to call ob_start().
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childLZlUc5
Child process created. PID = 29042
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childLZlUc5
About to call ob_start().
About to call ob_start().
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child7cSNNY
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-child7cSNNY
About to call ob_start().
About to call ob_start().
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
About to write file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childkRG6dF
Retrieving contents of file /private/var/folders/3_/nz1_2g_927sf2hp3k2xb3mr40000gn/T/phpcs-childkRG6dF
string(165) "<?php
$childOutput = array (
'totalFiles' => 0,
'totalErrors' => 0,
'totalWarnings' => 0,
'totalFixable' => 0,
'totalFixed' => 0,
);
$debugOutput = '';
?>"
..... 5 / 5 (100%) I can't find any reference to what's intentionally changed regarding output buffering for PHP 7.3. I use I commented out the I commented out the following, it worked: $file = $todo->current();
if ($file->ignored === true) {
continue;
}
...
$this->processFile($file); If any of them was uncommented, it failed again (that latter two because I looked more into FileList::current() - if I returned early from this, it worked. |
If it helps I had the same issue in PHP 7.3.1, but it stopped when I upgraded to PHP 7.3.2. |
Actually that may be a false positive, it started happening again after the first run, so upon php upgrade the first run was ok, the second and all since then, not. |
Brought to this issue upon searching for the error message. Using OSX with Homebrew, PHPCS version 3.4.0 with PHP 7.3.2 PHP Version output
PHPCS Version output
Error output
|
Just an update, after switching to php 7.2.15, error disappeared.
|
I am also running into this this issue running macOS Mojave (10.14.3) ❯ php --version
PHP 7.3.2 (cli) (built: Feb 5 2019 22:19:09) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.2, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.2, Copyright (c) 1999-2018, by Zend Technologies
❯ phpcs --version
PHP_CodeSniffer version 3.4.0 (stable) by Squiz (http://www.squiz.net)
❯ phpcs .
PHP Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined variable: childOutput in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 712 in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php:569
Stack trace:
#0 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(712): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined varia...', '/Users/ryan/.co...', 712, Array)
#1 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(509): PHP_CodeSniffer\Runner->processChildProcs(Array)
#2 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#3 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#4 {main}
thrown in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 569
Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined variable: childOutput in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 712 in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php:569
Stack trace:
#0 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(712): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined varia...', '/Users/ryan/.co...', 712, Array)
#1 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(509): PHP_CodeSniffer\Runner->processChildProcs(Array)
#2 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#3 /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#4 {main}
thrown in /Users/ryan/.composer/vendor/squizlabs/php_codesniffer/src/Runner.php on line 569 |
Update on this? |
I'm still unable to replicate this issue, even using the same OS and PHP versions as stated here. If anyone can provide a repo or container or anything to help replicate the problem, I'd be very grateful. |
had the same issue on a Mac with php 7.3.3. |
We had the same issue and for us it seems related to "symlinked" files and "parallel" execution?
|
I've just tried running over symlinked files with parallel execution of PHP 7.3 and still can't replicate any failures. |
@gsherwood I was earlier running PHPCS 3.4.0, today I upgraded to 3.4.1 but still the error persists |
I've managed to replicate this with a new brew installed version of PHP 7.3.4. Comparing that to my known working versions of 7.3, I've found that this php.ini setting appears to be the problem:
Note that it is commented out, but the default value is obviously to enable this. Disabling this fixes the problems for me, and reflects what my working 7.3 installs have already done by default:
I debugged PHPCS as far as I could to determine why the child processes were failing, but it looked like the process just died between function calls. But this is a regex extension and I did notice that leaving the EOL char of files empty did allow the script to continue longer, but die from other reasons. I'll keep looking into this to see if there is a particular regex that the jit is breaking. If I can't find one, I'll see if I can disable or detect this ini setting during a PHPCS run, or just detect that the child process has died and fail the entire run (means you wont be able to use the parallel option with the jit enabled). |
From the Generic standard, these are the sniffs that each cause errors when the jit is enabled:
|
I thought this was caused by complex regular expressions, but changing the TODO code to just be: $matches = [];
preg_match('/(.*)/', 'foo', $matches); Also causes the process to die. I'm not sure that I can actually fix this. I might need to disable the jit during PHPCS runs. |
… using the parallel option (ref #2304)
I ended up just disabling the pcre jit for PHPCS (c09a4e1). I couldn't figure out why the processes were dying and why a simple regex would kill it. I've also changed the process handling code so that PHPCS will die with a more specific error message rather than just an undefined var error. If anyone is able to test this fix, I'd be very grateful. Or even just disabling the jit in your php.ini to confirm that is the cause for you as well. |
I can confirm that turning off JIT for PHP 7.3, allows PHPCS to run with parallel > 1. |
@GaryJones Thanks for testing that for me. |
It Works 😃 @gsherwood Thanks for being so patient with this bug and helping us out 🤔 Still wondering why it works with JIT enabled on PHP 7.2 but not on PHP 7.3 |
Found this on PHP 7.3 Migration notes, worth looking into to resolve this without disabling JIT performance benefits https://www.php.net/manual/en/migration73.other-changes.php#migration73.other-changes.pcre So in PHP 7.3 they upgraded PCRE to PCRE2. This has caused issues in many other projects as well. |
That's what I was trying to do, but it appeared that simple calling preg_match was enough to silently segfault or something, no matter what regex or string I used. But only when running after forking, and even then it wasn't the first regex that PHPCS was using. So I'm a bit lost on this. |
Thanks @GaryJones and @gagan0123 for testing. I'm going to close this so this change can be released in 3.4.2. If anyone is continuing to have issues that this fix does not resolve, then it is likely to be a different problem and a new issue should be opened. If anyone has any idea how to get the parallel option working with the jit, please open an issue to discuss that as well. Thanks to everyone who provided info to help track this down. |
This may need to be investigated by PHP itself - has anyone checked if there are bugs reported against PHP 7.3 for PCRE2 vs the |
@jrfnl Yes there are several projects that started reporting issues because of PCRE2 update, but most of them simply disabled @gsherwood Creating new issue for support of |
@gagan0123 Thanks for checking. If disabling This, to me, still sounds more like a problem with the PCRE2 implementation in PHP 7.3 itself and possibly support for |
@jrfnl You're right, its not compatibility with PCRE2 thats causing the issue. I profiled the command using xdebug and with some luck found the exact line causing the issue. Currently child processes in PHPCS are failing at But I doubt this line if of any concern, since child processes are quitting at any preg_match statement in a forked process with Segmentation Fault signal(SIGSEGV). Its an issue localised to PHP 7.3.x running on MacOS. I've tested on Ubuntu 18.04 with PHP 7.3.3-1+ubuntu18.04.1+deb.sury.org+1 and it works perfectly fine. So I don't think we should hamper the performance benefits of having Right now building docker image with PHP 7.3 on alpine, once its built, will test on that as well. |
Update: It even works with PHP 7.3.4 on Alpine as well. |
@gagan0123 Oh wow! Well done with the debugging! If it helps: I was never able to reproduce the issue on Windows, so can confirm, based on one user testing, that things work fine on Windows.
Just had a quick look at that regex, even though it may not be the actual issue. I know PCRE2 is stricter regarding syntax and the if (preg_match("/(?:\r\n?|\n)/", $contents, $matches) !== 1) { |
Thanks for confirming it works on Windows 😃 I tested with parentheses as well, but it didn't work either, thing is, on MacOS, any statement with Learnt a lot while debugging this issue, thanks to @yoeunes for bringing this up 👍 |
So, if I understand you correctly, that basically just confirms that this is an issue which needs to be solved in PHP Core (or possibly MacOS), not in PHP userland code. A search of the PHP bug tracker yielded this issue which I believe is the closest match: https://bugs.php.net/bug.php?id=77260 @gagan0123 It might help get the issue resolved if you (or someone else who can reproduce the issue) would add details of the findings from this ticket to that thread. |
Just a note that during my debugging yesterday, my child processes were not directly failing here. I was able to echo content after the preg_match had completed and have that successfully output to screen for the child process. I could also exit after the preg_match and have the child process exit normally. But by the time the function had returned its value back to the caller, the process was dead. I've been unable to replicate the issue in a test script, otherwise I'd report it. |
Description
I get this exception when i run phpcs using a parallel value greater than 1
this is my phpcs.xml file:
The text was updated successfully, but these errors were encountered: