I'm continuing to try and move our build from cppcheck 1.86 up to 1.90+HEAD. I've found another issue.
All of my tests so far have been running on native on my Linux system. Our build system however uses a VM. When I updated the VM to use the newer cppcheck I found that the MISRA check was getting killed.
The problem is that the memory useage of the current development version increases significatly when rule suppressions are used. Our VM only had 1Gig of RAM allocated to it. MISRA eats that up and the OOM killer triggers.
Using memory_profiler on my development machine I've tracked it down to using suppressions. The more rules that are suppressed the more memory it uses. I've only been looking to the while program using mprof run misra.py <options> and not with the @profile annotations memory_profiler provides.
I have been comparing devlopement with 1.86. See below. I have not done any bisection of versions inbetween 1.96 and development. With all the structural changes that occurred lately A/B testing is a PITA.
Heres' some current memory useage numbers. Values are in megs. Source code tree is identical in all runs.
1.86 10 rules active
MEM 780.019531
1.90+HEAD
0 rules
MEM 784.515625
1 rules
MEM 852.695312
2 rules
MEM 1511.367188
4 rules.dat
MEM 1732.757812
10 rules
MEM 1778.050781
You can see that 1.86 with 10 rules has the same memory uses as no rules when using developement. When rules suppressions are used the memory usage increses by a large margin.
On a different but related note. If you watch misra.py's memory usage over time even 1.86 seems to be excessive (780 megs? Thats really large) as the program runs the memory usage steadly increases. Perhaps the new objects that are created as it checks each new file are not released when it moves to a new file?
In our setup we feed misra.py what is esentially misra.py *.dump. The result is 111 files provided on the command line.
I can't really put up my code base for test. Are there any open source projects using the MISRA checker that can try to duplicate my findings?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The regression first appears in version 1.89 although I was unable to test version 1.88 because it just thows an execption when I try to run it.
Which Python version are you using?
Does it make any difference using Python 2 compared to Python 3?
I did that testing with python2.7. I didn't know python3 was fully supported. Do the unit tests now work when using python3?
Python2 vs 3 does make a differenece. Although the regression still exists.
With python3 HEAD only uses a 728.906250 vs 1.87 using 305.074219
with the same setup.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes Python 3 is (or really should be) fully supported for the addon scripts. Otherwise it is a bug.
The unit tests for the addons are currently only executed with Python 2 by Travis. But i made a Pull Request to add execution with Python 3 also: https://github.com/danmar/cppcheck/pull/2185
Locally the addon unit tests work with Python 3.
There are other tests for the addons that are already executed with Python 2 and Python 3 by Travis.
Regarding your issue i do not really have an idea how to solve that, but i have not that deep of an insight into the addon scripts.
How does your command line and especially the suppressions look like? Can you paste the suppressions with censored file names/paths or so? Maybe that helps to reproduce or find the issue.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
=============================================================================== ERRORS ================================================================================ ________ ERROR at setup of testloadRuleTexts_structure __________
addons/misra.py:2321: in parseDump
data = cppcheckdata.parsedump(dumpfile)
addons/cppcheckdata.py:800: in parsedump
return CppcheckData(filename)
addons/cppcheckdata.py:757: in init
tok = Token(node)
Regarding your issue i do not really have an idea how to solve that, but i have not that deep of an insight into the addon scripts.
How does your command line and especially the suppressions look like? Can you paste the suppressions with censored file names/paths or so? Maybe that helps to reproduce or find the issue.
I have tested it with various arguments. The problem occurs either by adding global suppressions using --suppress-rules or by incorporating them into the .dump file by using --suppressions-list= from cppcheck. This would be expected since the acutall implementation of the rules is the same in both cases. Only the loading method is different. All the other arguments I've tested to not have any effect.
I've narrowed re-createing the problem down to the number of files included on the commnd line. There are 2 issues:
First the ammount of memory appear to grow as you check more files ie:
where you can replace 'file1.c.dump' in the 2nd example with any of the other files. This happens in both 1.90 and 1.87
2nd is that the amount by which that memory increases is much larger if you do that test using 1.90 vs 1.87
The test files I'm using are the ones in our code base that generate the largest dump files. The biggest (file1.c.dump) is 7Megs and the other 2 are 5 Megs and 4 Megs.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That command line came from the comment in the ./addons/test/test-misra.py file
That file needs updating with the correct usage.
Using your updated command line I still have failures but now the failure is the same for both python 2 and python 3. :) I've pasted the 1st failure below there are multiple failures with the same error.
pytest-3.3.2 is what is in Ubutu LTS 18 if the tests require a minimum version of pytest then they should check for that. I susggest that rules be added to the build system that check for minimim versions of the packages required and warnings genearated if they are not satisfied. Not matching the tests probally should not be an error but there should be a warning at minimum.
Doing the units tests shoul also have its own build target so you can do make test and have check dependencies and then run all the units tests.
I have figued out my problem.
Updating pytest did not fix it so I looked into it a bit more and noticed that the eception occurs in parse_dump() and I realized that I have seen this error before. The error occurs when there is a mismatch between the version of cppcheck used to create the dump file and the version of misra.py run.
The units tests use ./cppcheck to generate the .dump files and in my case that is from an older cppcheck.
If I change dump_create() to use ./build/bin/cppcheck instead of ./cppcheck
This would be another arguement for a make test so you can standarize the enviroment prior to running the tests.
The problem occurs on my system because I have small little helper scripts for building cppcheck due to all the changes across the versions. Some version need SRCDIR, some need, MATCHCOMPILER, some need FILESDIR, etc. For cppcheck < 1.90 I was using the make based build but for 1.90 I switched to using CMake. Aparently the CMake build does not update ./cppcheck and so I had a version mismatch.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm continuing to try and move our build from cppcheck 1.86 up to 1.90+HEAD. I've found another issue.
All of my tests so far have been running on native on my Linux system. Our build system however uses a VM. When I updated the VM to use the newer cppcheck I found that the MISRA check was getting killed.
The problem is that the memory useage of the current development version increases significatly when rule suppressions are used. Our VM only had 1Gig of RAM allocated to it. MISRA eats that up and the OOM killer triggers.
Using memory_profiler on my development machine I've tracked it down to using suppressions. The more rules that are suppressed the more memory it uses. I've only been looking to the while program using
mprof run misra.py <options>
and not with the @profile annotations memory_profiler provides.I have been comparing devlopement with 1.86. See below. I have not done any bisection of versions inbetween 1.96 and development. With all the structural changes that occurred lately A/B testing is a PITA.
Heres' some current memory useage numbers. Values are in megs. Source code tree is identical in all runs.
1.86 10 rules active
MEM 780.019531
1.90+HEAD
0 rules
MEM 784.515625
1 rules
MEM 852.695312
2 rules
MEM 1511.367188
4 rules.dat
MEM 1732.757812
10 rules
MEM 1778.050781
You can see that 1.86 with 10 rules has the same memory uses as no rules when using developement. When rules suppressions are used the memory usage increses by a large margin.
On a different but related note. If you watch misra.py's memory usage over time even 1.86 seems to be excessive (780 megs? Thats really large) as the program runs the memory usage steadly increases. Perhaps the new objects that are created as it checks each new file are not released when it moves to a new file?
In our setup we feed misra.py what is esentially
misra.py *.dump
. The result is 111 files provided on the command line.I can't really put up my code base for test. Are there any open source projects using the MISRA checker that can try to duplicate my findings?
spontanously .. it sounds strange that suppressions requre lots of memory.
I don't know. :-(
Which Python version are you using?
Does it make any difference using Python 2 compared to Python 3?
The regression first appears in version 1.89 although I was unable to test version 1.88 because it just thows an execption when I try to run it.
I did that testing with python2.7. I didn't know python3 was fully supported. Do the unit tests now work when using python3?
Python2 vs 3 does make a differenece. Although the regression still exists.
With python3 HEAD only uses a 728.906250 vs 1.87 using 305.074219
with the same setup.
Yes Python 3 is (or really should be) fully supported for the addon scripts. Otherwise it is a bug.
The unit tests for the addons are currently only executed with Python 2 by Travis. But i made a Pull Request to add execution with Python 3 also: https://github.com/danmar/cppcheck/pull/2185
Locally the addon unit tests work with Python 3.
There are other tests for the addons that are already executed with Python 2 and Python 3 by Travis.
Regarding your issue i do not really have an idea how to solve that, but i have not that deep of an insight into the addon scripts.
How does your command line and especially the suppressions look like? Can you paste the suppressions with censored file names/paths or so? Maybe that helps to reproduce or find the issue.
Doesn't work for me. Should probablly take this into another thread.
rsmith@rsmith-xps13:/home/src/cppcheck.git$ python3 -m pytest addons/test/test-misra.py
========================================================================= test session starts =========================================================================
platform linux -- Python 3.6.8, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/src/cppcheck.git, inifile:
collected 9 items
addons/test/test-misra.py EEEEEEEEF [100%]
=============================================================================== ERRORS ================================================================================
________ ERROR at setup of testloadRuleTexts_structure __________
addons/test/test-misra.py:26:
addons/misra.py:18: ModuleNotFoundError
Also I don't think the unit tests for misra.py in python2 are actually gettting run because they currently generate errors.
rsmith@rsmith-xps13:/home/src/cppcheck.git$ python -m pytest addons/test/test-misra.py
========================================================================= test session starts =========================================================================
platform linux2 -- Python 2.7.15+, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/src/cppcheck.git, inifile:
collected 9 items
addons/test/test-misra.py .....FFF. [100%]
============================================================================== FAILURES ===============================================================================
____________ test_json_out ______________
checker = <addons.misra.misrachecker instance="" 0x7f197bf103f8="" at="">, capsys = <_pytest.capture.CaptureFixture instance at 0x7f197bf10d40></addons.misra.misrachecker>
addons/test/test-misra.py:74:
addons/misra.py:2321: in parseDump
data = cppcheckdata.parsedump(dumpfile)
addons/cppcheckdata.py:800: in parsedump
return CppcheckData(filename)
addons/cppcheckdata.py:757: in init
tok = Token(node)
self = <addons.cppcheckdata.token instance="" at="" 0x7f197b4e27e8="">, element = <element 0x7f197bf04b50="" at="" 'tok'=""></element></addons.cppcheckdata.token>
addons/cppcheckdata.py:254: TypeError
I have tested it with various arguments. The problem occurs either by adding global suppressions using --suppress-rules or by incorporating them into the .dump file by using --suppressions-list= from cppcheck. This would be expected since the acutall implementation of the rules is the same in both cases. Only the loading method is different. All the other arguments I've tested to not have any effect.
I've narrowed re-createing the problem down to the number of files included on the commnd line. There are 2 issues:
First the ammount of memory appear to grow as you check more files ie:
python misra.py --suppress-rules = "5.4,11.4,13.1" file1.c.dump file2.c.dump file3.c.dump
uses more ram than:
python misra.py --suppress-rules = "5.4,11.4,13.1" file1.c.dump
where you can replace 'file1.c.dump' in the 2nd example with any of the other files. This happens in both 1.90 and 1.87
2nd is that the amount by which that memory increases is much larger if you do that test using 1.90 vs 1.87
The test files I'm using are the ones in our code base that generate the largest dump files. The biggest (file1.c.dump) is 7Megs and the other 2 are 5 Megs and 4 Megs.
oops. That should be
python misra.py --suppress-rules "5.4,11.4,13.1" file1.c.dump file2.c.dump file3.c.dump
According to the Travis log files and my local tests it works.
The command lines are slightly different from the ones you used:
That command line came from the comment in the ./addons/test/test-misra.py file
That file needs updating with the correct usage.
Using your updated command line I still have failures but now the failure is the same for both python 2 and python 3. :) I've pasted the 1st failure below there are multiple failures with the same error.
Here is the output when executing it locally on my debian system:
I remember that someone reported problems with the wrong/old pytest version.
Travis explicitly uses pytest 4.6.4 with Python 2. See commit https://github.com/danmar/cppcheck/commit/413a5a486571c04197c966fefe780fc54aeedc9c#diff-354f30a63fb0907d4ad57269548329e3
The output with Python 3 on my local system is this:
I have updated the documentation about running the tests:
https://github.com/danmar/cppcheck/commit/dc1cdd2b761e3f521269d44ead39d1a5d7488ff2
I hope it helps, if anything is unclear or could still be enhanced we can further improve it.
pytest-3.3.2 is what is in Ubutu LTS 18 if the tests require a minimum version of pytest then they should check for that. I susggest that rules be added to the build system that check for minimim versions of the packages required and warnings genearated if they are not satisfied. Not matching the tests probally should not be an error but there should be a warning at minimum.
Doing the units tests shoul also have its own build target so you can do
make test
and have check dependencies and then run all the units tests.I have figued out my problem.
Updating pytest did not fix it so I looked into it a bit more and noticed that the eception occurs in parse_dump() and I realized that I have seen this error before. The error occurs when there is a mismatch between the version of cppcheck used to create the dump file and the version of misra.py run.
The problem is due to the following:
The units tests use ./cppcheck to generate the .dump files and in my case that is from an older cppcheck.
If I change dump_create() to use ./build/bin/cppcheck instead of ./cppcheck
This would be another arguement for a
make test
so you can standarize the enviroment prior to running the tests.The problem occurs on my system because I have small little helper scripts for building cppcheck due to all the changes across the versions. Some version need SRCDIR, some need, MATCHCOMPILER, some need FILESDIR, etc. For cppcheck < 1.90 I was using the make based build but for 1.90 I switched to using CMake. Aparently the CMake build does not update ./cppcheck and so I had a version mismatch.
Opps. Editing error.
Shoud be:
If I change dump_create() to use ./build/bin/cppcheck instead of ./cppcheck it works and the unit tests complete without problems.
I fixed it. Here is PR with issue description: https://github.com/danmar/cppcheck/pull/2321
@whoopsmith could you please check this version?