Linter cpplint throws PhutlilAggregateException on windows

Hello!
This is a continuation of Arc lint hangs / does not terminate for cppcheck / cpplint

So I try to run the linter cpplint on a windows client. The python command python cpplint.py test.cpp runs successfully.
Executing arc lint test.cpp --trace returns the following output:

[2020-04-29 13:59:46] EXCEPTION: (PhutilAggregateException) Some linters failed:
- CommandException: Command failed with error #1!
COMMAND
cpplint.py “C:\HIWI\Phabricator\testingRepo\test.cpp”

  STDOUT
  (empty)

  STDERR
  Call to "proc_open()" to open a subprocess failed: proc_open(): CreateProcess failed, error code - 193 at [<arcanist>\src\lint\engine\ArcanistLintEngine.php:264]

arcanist(head=master, ref.master=6ec09b2f482a)
#0 <#2> ExecFuture::raiseResultError(array) called at [\src\future\exec\ExecFuture.php:313]
#1 <#2> ExecFuture::resolvex() called at [\src\lint\linter\ArcanistExternalLinter.php:448]
#2 <#2> ArcanistExternalLinter::resolveFuture(string, ExecFuture) called at [\src\lint\linter\ArcanistFutureLinter.php:35]
#3 <#2> ArcanistFutureLinter::didLintPaths(array) called at [\src\lint\engine\ArcanistLintEngine.php:595]
#4 <#2> ArcanistLintEngine::executeDidLintOnPaths(ArcanistCpplintLinter, array) called at [\src\lint\engine\ArcanistLintEngine.php:546]
#5 <#2> ArcanistLintEngine::executeLintersOnChunk(array, array) called at [\src\lint\engine\ArcanistLintEngine.php:474]
#6 <#2> ArcanistLintEngine::executeLinters(array) called at [\src\lint\engine\ArcanistLintEngine.php:206]
#7 ArcanistLintEngine::run() called at [\src\workflow\ArcanistLintWorkflow.php:219]
#8 ArcanistLintWorkflow::run() called at [\scripts\arcanist.php:411]

Next I copied the installed binary of cpplint.exe (generated by pip and python(3.7) and lying in the python directory). Then I changed the getDefaultBinary from cpplint.py to cpplint.exe in the ArcanistCpplintLinter.php file. Then the following error occurs:

[2020-04-29 14:35:53] EXCEPTION: (RuntimeException) Undefined offset: -1 at [\src\error\PhutilErrorHandler.php:258]
arcanist(head=master, ref.master=6ec09b2f482a)
#0 PhutilErrorHandler::handleError(integer, string, string, integer, array) called at [\src\lint\renderer\ArcanistConsoleLintRenderer.php:251]
#1 ArcanistConsoleLintRenderer::renderContext(ArcanistLintMessage, string, array) called at [\src\lint\renderer\ArcanistConsoleLintRenderer.php:91]
#2 ArcanistConsoleLintRenderer::renderLintResult(ArcanistLintResult) called at [\src\workflow\ArcanistLintWorkflow.php:296]
#3 ArcanistLintWorkflow::run() called at [\scripts\arcanist.php:411]

Is there any solution for this problem?

python --version
Python 3.7.0

$ cpplint --version
Cpplint fork (https://github.com/cpplint/cpplint)
cpplint 1.4.5

$ php --version
PHP 7.3.3 (cli) (built: Mar 6 2019 21:53:23) ( ZTS MSVC15 (Visual C++ 2017) x64)
Copyright © 1997-2018 The PHP Group
Zend Engine v3.3.3, Copyright © 1998-2018 Zend Technologies

$ git --version
git version 2.26.2.windows.1

git-gui version 0.21.GITGUI

$ cppcheck --version
Cppcheck 1.90

$ arc version
arcanist 6ec09b2f482a6e6855c32da045b97d698db36aef (28 Apr 2020)

Thanks in advance!

It looks like cpplint support in Arcanist has been broken for a while - https://secure.phabricator.com/T8404 is from 2015. The latest comment there links to an external library that adds a newer support for cpplint, but that library hasn’t been updated in about 4 years either.

You might be looking at writing your own extension for this…

The second exception, at least, is a bug either in Arcanist itself or in our validation of lint messages. It is probably a pre-existing bug which was made more severe by the changes in https://secure.phabricator.com/D21044.

However, I can’t figure out how to reproduce it without explicitly raising a lint message on line “-1”, and I don’t see how the upstream “cpplint” linter can ever do that.

I may be able to fix this bug if you can try this: first, run arc lint <path> --trace.

$ arc lint <path> --trace

The output should include the raw “cpplint” command that arc is executing, e.g. something like:

>>> [11] (+26) <exec> $ cpplint test.cpp

Find that command in the --trace output, then run it on its own and copy/paste the output it generates here?

As @avivey points out, a lot of linters were contributed upstream in 2011-2014 and they became impossible to maintain, so fully fixing the binding may be out of scope until T8404 moves forward, but the second error isn’t a problem with the binding.

According to the command of the first example (executing with cpplint.py) there is missing the “python” in the command for correct execution (See [5] (+345)):

Found 1 matching paths for linter ‘forCppChecks’.
[1] (+0) where cpplint.py [1] (+169) <exec> 169,333 us [2] (+170) <lint> C++ Google's Styleguide <paths = 1> [3] (+170) <exec> where cpplint.py
[3] (+344) 174,185 us
[2] (+345) 175,005 us
[4] (+345) C++ Google’s Styleguide <paths = 1>
[5] (+345) $ cpplint.py “C:\HIWI\Phabricator\testingRepo\test.cpp”
[5] (+352) 6,981 us
[4] (+353) 8,395 us
[2020-04-30 16:16:54] EXCEPTION: (PhutilAggregateException) Some linters failed:
- CommandException: Command failed with error #1!
COMMAND
cpplint.py “C:\HIWI\Phabricator\testingRepo\test.cpp”

  STDOUT
  (empty)

  STDERR
  Call to "proc_open()" to open a subprocess failed: proc_open(): CreateProcess failed, error code - 193 at [<arcanist>\src\lint\engine\ArcanistLintEngine.php:264]

arcanist(head=master, ref.master=696ec3f97585)
#0 <#2> ExecFuture::raiseResultError(array) called at [\src\future\exec\ExecFuture.php:313]
#1 <#2> ExecFuture::resolvex() called at [\src\lint\linter\ArcanistExternalLinter.php:448]
#2 <#2> ArcanistExternalLinter::resolveFuture(string, ExecFuture) called at [\src\lint\linter\ArcanistFutureLinter.php:35]
#3 <#2> ArcanistFutureLinter::didLintPaths(array) called at [\src\lint\engine\ArcanistLintEngine.php:595]
#4 <#2> ArcanistLintEngine::executeDidLintOnPaths(ArcanistCpplintLinter, array) called at [\src\lint\engine\ArcanistLintEngine.php:546]
#5 <#2> ArcanistLintEngine::executeLintersOnChunk(array, array) called at [\src\lint\engine\ArcanistLintEngine.php:474]
#6 <#2> ArcanistLintEngine::executeLinters(array) called at [\src\lint\engine\ArcanistLintEngine.php:206]
#7 ArcanistLintEngine::run() called at [\src\workflow\ArcanistLintWorkflow.php:219]
#8 ArcanistLintWorkflow::run() called at [\scripts\arcanist.php:411]

[5] (+345) $ cpplint.py “C:\HIWI\Phabricator\testingRepo\test.cpp”

Or am I wrong? Executing the command above won’t work without “python” as prefix of the command resulting as command on its own:

$ cpplint.py test.cpp
bash: cpplint.py: command not found

Correct would be:

$ python cpplint.py test.cpp
test.cpp:0: No copyright message found. You should have a line: "Copyright [year] " [legal/copyright] [5]
test.cpp:2: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces] [5]
test.cpp:4: Missing space before { [whitespace/braces] [5]
test.cpp:5: Tab found; better to use spaces [whitespace/tab] [1]
test.cpp:6: Tab found; better to use spaces [whitespace/tab] [1]
test.cpp:6: Missing spaces around = [whitespace/operators] [4]
test.cpp:8: Tab found; better to use spaces [whitespace/tab] [1]
Done processing test.cpp
Total errors found: 7


Now the second example (executing cpplint.exe):
arc lint test.cpp --trace returns:

[1] (+0) where cpplint.exe [1] (+170) <exec> 170,534 us [2] (+171) <lint> C++ Google's Styleguide <paths = 1> [3] (+171) <exec> where cpplint.exe
[3] (+342) 170,817 us
[2] (+343) 171,587 us
[4] (+343) C++ Google’s Styleguide <paths = 1>
[5] (+343) $ cpplint.exe “C:\HIWI\Phabricator\testingRepo\test.cpp”
[5] (+534) 191,020 us
[4] (+536) 193,461 us

[2020-04-30 16:10:08] EXCEPTION: (RuntimeException) Undefined offset: -1 at [\src\error\PhutilErrorHandler.php:258]
arcanist(head=master, ref.master=696ec3f97585)
#0 PhutilErrorHandler::handleError(integer, string, string, integer, array) called at [\src\lint\renderer\ArcanistConsoleLintRenderer.php:251]
#1 ArcanistConsoleLintRenderer::renderContext(ArcanistLintMessage, string, array) called at [\src\lint\renderer\ArcanistConsoleLintRenderer.php:91]
#2 ArcanistConsoleLintRenderer::renderLintResult(ArcanistLintResult) called at [\src\workflow\ArcanistLintWorkflow.php:296]
#3 ArcanistLintWorkflow::run() called at [\scripts\arcanist.php:411]

Executing the raw command $ cpplint.exe "C:\HIWI\Phabricator\testingRepo\test.cpp" returns:
Done processing C:\HIWI\Phabricator\testingRepo\test.cpp
Total errors found: 7
C:\HIWI\Phabricator\testingRepo\test.cpp:0: No copyright message found. You should have a line: "Copyright [year] " [legal/copyright] [5]
C:\HIWI\Phabricator\testingRepo\test.cpp:2: Do not use namespace using-directives. Use using-declarations instead. [build/namespaces] [5]
C:\HIWI\Phabricator\testingRepo\test.cpp:4: Missing space before { [whitespace/braces] [5]
C:\HIWI\Phabricator\testingRepo\test.cpp:5: Tab found; better to use spaces [whitespace/tab] [1]
C:\HIWI\Phabricator\testingRepo\test.cpp:6: Tab found; better to use spaces [whitespace/tab] [1]
C:\HIWI\Phabricator\testingRepo\test.cpp:6: Missing spaces around = [whitespace/operators] [4]
C:\HIWI\Phabricator\testingRepo\test.cpp:8: Tab found; better to use spaces [whitespace/tab] [1]

I hope this is understandable.

This is likely fixed by changes connected to https://secure.phabricator.com/T13543.

1 Like

I have upgraded to the following version of arcanist
arcanist 33dfa859d8e68a66559c15c78cea4da19204653b (12 Jun 2020)

The cpplint is still throwing an exception if the function getDefaultBinary() in ArcanistCpplintLinter.php returns ‘cpplint.py’.

But if you change the return value of the binary to cpplint.exe it works.

If executed in gitbash, the below python path has to be provided in the .bashrc file (because cpplint.exe lies there in my case).
PATH=$PATH:/c/“Program Files”/Python37/Scripts
If executed with cmd it might has to to be added to the environment path variables.

Thanks for fixing this issue!