SublimeLinter / SublimeLinter-php

SublimeLinter 3 plugin for PHP, using php -l.
MIT License
209 stars 29 forks source link

Process PHP with 100% CPU usage #12

Closed kokokurak closed 8 years ago

kokokurak commented 9 years ago

I'm on OS X Yosemite. From time to time, for me like about every hour, SublimeLinter-php is starting PHP task with 100% CPU usage. It never stops, unless I stop the task manually. I didn't know what starts that task, but found out that the issue is gone when I disable SublimeLinter-php.

ghost commented 9 years ago

Do you have any other SublimeLinter plugins installed? If so, do they ever cause similar problems?

Also, what do you find in the Sublime Text console (Cmd+`)? Could you copy its contents into a comment, please?

kokokurak commented 9 years ago

@Aedx Yes, I use more Linters, but this is the only one that causes problems. I will paste console's contents when it happens again.

kokokurak commented 9 years ago

Okay, I encountered this issue again. The only thing in the console I'm not sure about is:

indexing [queue 339]: no files were indexed out of the 1 queued, abandoning crawl
groteworld commented 9 years ago

Are you in background or save only linting?

kokokurak commented 9 years ago

Background linting.

ghost commented 9 years ago

Is the linter running on saved files only, or in new buffers also?

kokokurak commented 9 years ago

Um, I just answered that I believe.

ghost commented 9 years ago

Sorry, to clarify: does it run on files already on your hard disk only, or on files not yet saved to your hard disk?

kokokurak commented 9 years ago

It runs on new (unsaved) files as well, but I rarely add new files. The problem occurs on existing files for sure.

kokokurak commented 9 years ago

It happened again, it's so annoying :( My fan starts to work like crazy and sometimes SublimeText freezes.

kokokurak commented 9 years ago

And again...

ghost commented 9 years ago

I suggest that you disable the plugin until a solution is found, and instead use php -l -n -d display_errors=On -d log_errors=Off <filename> from the command line.

ghost commented 9 years ago

The error appears to be originating from Sublime Text itself, and can be caused by a variety of things. It would be useful if you could keep your console open until it happens, so that we can see exactly what is going on.

kokokurak commented 9 years ago

Does it make a difference if I keep console opened or not? Does it skip logging some entries if it's hidden?

ghost commented 9 years ago

No, but it would allow you to see exactly what is logged when you experience the problem.

ghost commented 9 years ago

What do you have your index_exclude_patterns option set to? You can find this in Preferences > Settings - User.

kokokurak commented 9 years ago

My console doesn't have anything special, other than this one entry that I mentioned above:

indexing [queue 339]: no files were indexed out of the 1 queued, abandoning crawl

Other than this, it's only info that I saved a file.

In my index_exclude_patterns I had *.log files and vendor folder of some big project. I forgot to delete it. Can that be a problem?

ghost commented 9 years ago

Try setting the index_files flag to false, then see if it happens again. It may be that the error is not associated in any way with your problem.

groteworld commented 9 years ago

just some reasons I've seen in the past to try: corrupt/large Session.sublime-session (deleting file fixes it), or there is a empty directory in the project, or the user is using ST2 which for some reason had problems with it.

kokokurak commented 9 years ago

OK, removing this vendor folder from index_exclude_patterns didn't help. I deleted Session.sublime-session, let's see what happens.

akrabat commented 9 years ago

I get this a lot too.

groteworld commented 9 years ago

@kokokurak Update?

@akrabat Depending on kokokurak's update, you may want to follow what they did, if it fixed it.

kokokurak commented 9 years ago

Hi guys, sorry for the delay, but I haven't programmed for a while. The issue still occurs :(

kokokurak commented 9 years ago

Can I give you any more details?

kokokurak commented 9 years ago

Also, I can add that I use PHP 5.6 in CLI and 5.4 in Apache.

kokokurak commented 9 years ago

I'm trying to use PHP 5.4 in CLI instead, let's see what happens.

ghost commented 9 years ago

Any updates? Also, could you please paste the output from running ps -e | grep php in Terminal while you are getting high CPU usage? This would help to see if you have many duplicate php processes running.

kokokurak commented 9 years ago

@Aedx I will post an update soon. For now I disabled all PHP linters, because it was driving me crazy. I enabled them now and will let you know perhaps tomorrow.

kokokurak commented 9 years ago

@Aedx Here comes my result of ps -e | grep php after encountering the issue:

26612 ??         1:30.47 php /usr/local/bin/phpcs --report=checkstyle --standard=PSR2 /var/folders/z8/b7pr_03n7yd0w8p2d6wvms240000gn/T/SublimeLinter3-myname/add.php
26627 ttys000    0:00.01 grep php
ghost commented 9 years ago

@kokokurak Wow... You don't have duplicate processes like I suspected at first, but instead a single process which has been running with high CPU usage for about an hour and a half. Not good.

It is highly likely that the process is not being ended correctly when linting is finished, I will have to look into why this is happening.

groteworld commented 9 years ago

next time it comes around (I'm sorry, I hate that we have to say that, I wish we could replicate it), try to copy or get the contents of that file (E.g. /var/folders/z8/b7pr_03n7yd0w8p2d6wvms240000gn/T/SublimeLinter3-myname/add.php) when you do ps -e | grep php It may tell us something about what causes it to hang.

kokokurak commented 9 years ago

Hmm, I see this file contains just pure PHP code with no additional linter data. How can that help?

groteworld commented 9 years ago

I believe it is something in this  php code that is hanging up the php process. A loop, something. Not sure though.

On Sat, Mar 28, 2015 at 11:03 AM, kokokurak notifications@github.com wrote:

Hmm, I see this file contains just pure PHP code with no additional linter data. How can that help?

Reply to this email directly or view it on GitHub: https://github.com/SublimeLinter/SublimeLinter-php/issues/12#issuecomment-87241545

kokokurak commented 9 years ago

@skj3gg I think there is a chance that this bug occurs more often when I use new, short array syntax, but I can't prove nor confirm it. I just have a feeling that it triggers it.

sormy commented 9 years ago

The problem in phpcs. I tried to dump problem file and found that on that file phpcs actually hangs and constantly output:

PHP Notice:  Undefined index:  in /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/File.php on line 3411
PHP Stack trace:
PHP   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.0/scripts/phpcs:0
PHP   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.0/scripts/phpcs:25
PHP   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/CLI.php:95
PHP   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/CLI.php:867
PHP   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:619
PHP   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:1679
PHP   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:1801
PHP   8. Generic_Sniffs_WhiteSpace_ScopeIndentSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/File.php:567
PHP   9. PHP_CodeSniffer_File->findFirstOnLine() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php:219

and

PHP Notice:  Undefined index:  in /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/File.php on line 3423
PHP Stack trace:
PHP   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.0/scripts/phpcs:0
PHP   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.0/scripts/phpcs:25
PHP   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/CLI.php:95
PHP   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/CLI.php:867
PHP   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:619
PHP   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:1679
PHP   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer.php:1801
PHP   8. Generic_Sniffs_WhiteSpace_ScopeIndentSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/File.php:567
PHP   9. PHP_CodeSniffer_File->findFirstOnLine() /usr/local/Cellar/php-code-sniffer/2.3.0/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php:219

You could add error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING & ~E_DEPRECATED); into /usr/local/bin/phpcs after $cli = new PHP_CodeSniffer_CLI(); and it will actually remove all that comments but process anyway will hang and eats 100% cpu, so it's not a solution.

It seems like a bug in phpcs, I didn't tried to actually fix the problem but I found that for some reason function in /CodeSniffer/File.php receives unexpected $start value. I found that stupid workaround, which prevent hangs and allow phpcs to exit normally:

    public function findFirstOnLine($types, $start, $exclude=false, $value=null)
    {
        if (is_array($types) === false) {
            $types = array($types);
        }

        $foundToken = false;

        if ($start === "" || $start === null) {
            throw new \UnexpectedValueException("Died to save your money on electricity bill =)");
        }

        for ($i = $start; $i >= 0; $i--) {
            if ($this->_tokens[$i]['line'] < $this->_tokens[$start]['line']) {
                break;
            }
sormy commented 9 years ago

I think the best fix for SublimeLinter-php is to do not try to lint via phpcs/phpmd or something else if file is not valid based on php -l <filename> result. This situation occurs when you have background linting enabled and type temporarily invalid php code and that could kill phpcs.

sormy commented 9 years ago

This is the one of killing samples:

<?php

class PhpCsHang
{
    private function magicMethod()
    {
        $this->service1->doIt(
            $this->service2-"patient_last_name"),
            $this->service2-"patient_first_name"),
            $this->service2-"patient_middle_name")
        );
    }
}
sormy commented 9 years ago

phpcs v2.3.2 could not be killed by that sample =) so if you have that or like that problem - save buggy example temp file in external file, and submit to phpcs tracker

sormy commented 9 years ago

actually i found another one sample which could freeze phpcs 2.3.2

sormy commented 9 years ago

this easy sample makes phpcs burn your cpu:

<?php
foreach
kokokurak commented 9 years ago

I confirm that typing lonely foreach makes php process use 100% CPU!

ghost commented 9 years ago

@kokokurak Could you confirm that this is just with php -l instead of phpcs? If so, what comes of manually typing in the command produced by the linter plugin? Does it hang, or just return some error message similar to

PHP Parse error:  syntax error, unexpected end of file, expecting '(' in cpu-test.php on line 3
Errors parsing cpu-test.php

To avoid having to look through the plugin code, here is the command executed for a php file by this plugin:

php -l -n -d display_errors=On -d log_errors=Off <filename>

kokokurak commented 9 years ago

@Aedx What should I do? :) I don't know what you mean.

ghost commented 9 years ago

Firstly create a file, name it cpu-test.php and insert the following contents:

<?php
foreach

Then, open a Terminal in the directory within which cpu-test.php is located (or cd into it). Finally, execute php -l -n -d display_errors=On -d log_errors=Off cpu-test.php

All I really need to know is whether it returns an error message or hangs.

kokokurak commented 9 years ago

I checked it. It returns as follows:

Parse error: syntax error, unexpected end of file, expecting '(' in index.php on line 4
Errors parsing index.php
ghost commented 9 years ago

Could you please execute the following command:

php /usr/local/bin/phpcs --report=checkstyle --standard=PSR2 cpu-test.php

kokokurak commented 9 years ago

This command opens php process with 100% CPU usage and displays this:

PHP Notice:  Undefined index: parenthesis_closer in /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php on line 77
PHP Stack trace:
PHP   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:0
PHP   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:25
PHP   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:95
PHP   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:867
PHP   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:619
PHP   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1679
PHP   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1801
PHP   8. Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/File.php:567

Notice: Undefined index: parenthesis_closer in /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php on line 77

Call Stack:
    0.0002     226888   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:0
    0.0068    1539816   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:25
    0.0072    1598248   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:95
    0.0283    3508696   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:867
    0.0284    3510504   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:619
    0.0284    3510984   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1679
    0.0287    3537104   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1801
    0.0291    3570472   8. Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/File.php:567

PHP Notice:  Undefined offset: -1 in /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php on line 109
PHP Stack trace:
PHP   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:0
PHP   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:25
PHP   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:95
PHP   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:867
PHP   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:619
PHP   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1679
PHP   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1801
PHP   8. Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/File.php:567

Notice: Undefined offset: -1 in /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php on line 109

Call Stack:
    0.0002     226888   1. {main}() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:0
    0.0068    1539816   2. PHP_CodeSniffer_CLI->runphpcs() /usr/local/Cellar/php-code-sniffer/2.3.2/scripts/phpcs:25
    0.0072    1598248   3. PHP_CodeSniffer_CLI->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:95
    0.0283    3508696   4. PHP_CodeSniffer->processFiles() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/CLI.php:867
    0.0284    3510504   5. PHP_CodeSniffer->processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:619
    0.0284    3510984   6. PHP_CodeSniffer->_processFile() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1679
    0.0287    3537104   7. PHP_CodeSniffer_File->start() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer.php:1801
    0.0291    3570472   8. Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff->process() /usr/local/Cellar/php-code-sniffer/2.3.2/CodeSniffer/File.php:567

Killed: 9
ghost commented 9 years ago

Does it actually exit, or does it hang?

kokokurak commented 9 years ago

It hangs :)

kokokurak commented 9 years ago

It exits once I kill php process manually.