Menu

Cppcheck internalError on MISRA C rule 9

khouri
2021-03-30
2021-06-28
  • khouri

    khouri - 2021-03-30

    When running MISRA C checks on a third party codebase, cppcheck fails on some of the files with an internalError somewhere in the MISRA Python files. Cppcheck verson is 2.4.1.
    This is an example output (XML format) with project specific filenames/paths redacted:

    <error id="internalError" severity="information" msg="Bailing out from checking [filename redacted].c since there was an internal error: Failed to execute &apos;python3 /usr/share/cppcheck/addons/misra.py --cli --rule-texts=[path redacted]/misra_rules.txt --suppress-rules=11.4,11.5,15.5,3.1,11.3,11.6 [filename redacted].c.dump&apos;. Traceback (most recent call last):" verbose="  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3327, in &lt;module&gt;\n    main()\n  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3271, in main\n    checker.parseDump(item)\n  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3102, in parseDump\n    self.executeCheck(902, self.misra_9_2, cfg)\n  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3053, in executeCheck\n    check_function(*args)\n  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 1499, in misra_9_2\n    misra_9.misra_9_x(self, data, 902)\n  File &quot;/usr/share/cppcheck/addons/misra_9.py&quot;, line 406, in misra_9_x\n    parser.parseInitializer(ed, eq.astOperand2)\n  File &quot;/usr/share/cppcheck/addons/misra_9.py&quot;, line 305, in parseInitializer\n    elif self.token.isString and self.ed.valueType.pointer &gt; 0:\nAttributeError: &apos;NoneType&apos; object has no attribute &apos;pointer&apos;\n">
                <location file="[filename redacted].c" line="0" column="0"/>
    </error>
    

    After clean-up, this becomes:

    Bailing out from checking [filename redacted].c since there was an internal error: Failed to execute `python3 /usr/share/cppcheck/addons/misra.py --cli --rule-texts=[path redacted]/misra_rules.txt --suppress-rules=11.4,11.5,15.5,3.1,11.3,11.6 [filename redacted].c.dump`. 
    Traceback (most recent call last):
        File "/usr/share/cppcheck/addons/misra.py", line 3327, in <module>;
        main()
    
        File "/usr/share/cppcheck/addons/misra.py", line 3271, in main
        checker.parseDump(item)
    
        File "/usr/share/cppcheck/addons/misra.py", line 3102, in parseDump
        self.executeCheck(902, self.misra_9_2, cfg)
    
        File "/usr/share/cppcheck/addons/misra.py", line 3053, in executeCheck
        check_function(*args)
    
        File "/usr/share/cppcheck/addons/misra.py", line 1499, in misra_9_2
        misra_9.misra_9_x(self, data, 902)
    
        File "/usr/share/cppcheck/addons/misra_9.py", line 406, in misra_9_x
        parser.parseInitializer(ed, eq.astOperand2)
    
        File "/usr/share/cppcheck/addons/misra_9.py", line 305, in parseInitializer
        elif self.token.isString and self.ed.valueType.pointer > 0:
        AttributeError: `NoneType` object has no attribute `pointer`
    

    Due to time constraints, I can't try to extract an simple example case to trigger the behaviour at this time.
    If needed, can look into this later.

     

    Last edit: khouri 2021-03-30
  • Georgiy Komarov

    Georgiy Komarov - 2021-03-30

    Hello, thanks for reporting this.
    The third-party codebase you're talking about is open source? Can you show the code where the misra.py crashes or provide a minimal example?

     
  • khouri

    khouri - 2021-03-30

    This is not an open source code base. I also can't share the file itself, but I can try to create a minimal example soon (after deadlines).

     
    👍
    1
  • khouri

    khouri - 2021-06-21

    One of our interns dived into this (thx, Sander!) and we've managed to extract a minimum viable way of recreating the bug. Cppcheck version is 2.4.1.

    test.c:

    #include "datatypes.h"
    
    typedef struct {
        MY_UINT08     my_str[10];
    } EXAMPLE_STRUCT;
    
    static const EXAMPLE_STRUCT example_data = {
        .my_str    = "xxxxxxxxxx"
    };
    

    cppcheck command:

    cppcheck --enable=all --addon=misra.py --xml test.c
    

    Yields as output:

    <?xml version="1.0" encoding="UTF-8"?>
    <results version="2">
        <cppcheck version="2.4.1"/>
        <errors>
    Checking test.c ...
            <error id="internalError" severity="information" msg="Bailing out from checking test.c since there was an internal error: Failed to execute &apos;python3 /usr/share/cppcheck/addons/misra.py --cli test.c.dump&apos;. Traceback (most recent call last):" verbose="  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3327, in &lt;module&gt;\012    main()\012  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3271, in main\012    checker.parseDump(item)\012  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3102, in parseDump\012    self.executeCheck(902, self.misra_9_2, cfg)\012  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 3053, in executeCheck\012    check_function(*args)\012  File &quot;/usr/share/cppcheck/addons/misra.py&quot;, line 1499, in misra_9_2\012    misra_9.misra_9_x(self, data, 902)\012  File &quot;/usr/share/cppcheck/addons/misra_9.py&quot;, line 406, in misra_9_x\012    parser.parseInitializer(ed, eq.astOperand2)\012  File &quot;/usr/share/cppcheck/addons/misra_9.py&quot;, line 305, in parseInitializer\012    elif self.token.isString and self.ed.valueType.pointer &gt; 0:\012AttributeError: &apos;NoneType&apos; object has no attribute &apos;pointer&apos;\012">
                <location file="test.c" line="0" column="0"/>
            </error>
            <error id="missingInclude" severity="information" msg="Cppcheck cannot find all the include files (use --check-config for details)" verbose="Cppcheck cannot find all the include files. Cppcheck can check the code without the include files found. But the results will probably be more accurate if all the include files are found. Please check your project&apos;s include directories and add all of them as include directories for Cppcheck. To see what files Cppcheck cannot find use --check-config."/>
        </errors>
    </results>
    

    I think the problem is related to the missing include which holds the datatypes. Replacing "MY_UINT08" by "unsigned char" makes the internalError go away. Missing includes certainly require attention, but the internalError is likely not the desired behaviour.

    I hope this helps in reproducing the error.

     
    • Georgiy Komarov

      Georgiy Komarov - 2021-06-21

      Thanks for this minimal example.

      Could you please show how MY_UINT08 is defined in datatypes.h?

      I've tried to add the following lines to datatypes.h, but it doesn't produce any false positives:

      #ifndef DATATYPES_H
      #define DATATYPES_H
      
      #include <inttypes.h>
      
      // typedef unsigned char MY_UINT08;
      typedef uint8_t MY_UINT08;
      
      #endif // DATATYPES_H
      
       
      • khouri

        khouri - 2021-06-21

        In this example, there is no datatypes.h (or at least, it is not in the include paths given to cppcheck). If there were one, it would look like in your example.

        However, I think the fact that cppcheck doesn't know more about the MY_UINT08 type is what is actually causing the crash.

        One could argue that the datatypes.h file should always be provided to cppcheck, so that it would just know the type. But probably a more graceful means of handling this situation is intended than the crash observed here, when the definition is not given.

         
        • Georgiy Komarov

          Georgiy Komarov - 2021-06-24

          Thanks, here is suggested fix: https://github.com/danmar/cppcheck/pull/3305 .

           

          Last edit: Georgiy Komarov 2021-06-24
      • Richard Smith

        Richard Smith - 2021-06-23

        I think you may have missed this in the other thread. The following update to the test file will produce the problem.

        diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c
        index a0092160c..d15ebe805 100644
        --- a/addons/test/misra/misra-test.c
        +++ b/addons/test/misra/misra-test.c
        @@ -480,6 +480,7 @@ void misra_9_struct_initializers(void) {
             dummy_struct dsd[2][2] = { 1, 2, 3, 4 };                  // 9.2
             dummy_struct dse[3]    = { {1,2}, {3,4}, [1] = {5,6} };   // 9.3 9.4
             dummy_struct dsd[]     = { [0] = 1 };                     // 9.5
        +    dummy_struct dsg       = { .a = {0}, .b = {0} };
        
             // Obsolete initialization syntax for GCC
             struct1 os1 = { i1: 1, i2: 2 }; // 10.4 13.4
        
         
        • Richard Smith

          Richard Smith - 2021-06-23

          That was intended for Georgiy. Sorry if it appears like it is directed at khouri.

           
        • Georgiy Komarov

          Georgiy Komarov - 2021-06-24

          Thanks, it seems to be fixed in the main branch: https://github.com/danmar/cppcheck/pull/3290 .

           
          • khouri

            khouri - 2021-06-25

            My colleague just tested the updated cppcheck with a fresh build from the commit mentioned in the post above (thus incl. the fix).

            Using the test.c file described earlier as input, I'm sorry to say the internalError still persists.

             
            • Daniel Marjamäki

              I can't reproduce the internal error neither.

              When I test it with latest HEAD;

              $ ./cppcheck --enable=all --addon=misra.py --xml test.c
              <?xml version="1.0" encoding="UTF-8"?>
              <results version="2">
                  <cppcheck version="2.4"/>
                  <errors>
              Checking test.c ...
                      <error id="misra-c2012-9.2" severity="style" msg="misra violation (use --rule-texts=&lt;file&gt; to get proper output)" verbose="misra violation (use --rule-texts=&lt;file&gt; to get proper output)" file0="test.c">
                          <location file="test.c" line="7" column="29"/>
                      </error>
                      <error id="missingInclude" severity="information" msg="Cppcheck cannot find all the include files (use --check-config for details)" verbose="Cppcheck cannot find all the include files. Cppcheck can check the code without the include files found. But the results will probably be more accurate if all the include files are found. Please check your project&apos;s include directories and add all of them as include directories for Cppcheck. To see what files Cppcheck cannot find use --check-config."/>
                  </errors>
              </results>
              

              I doubt that the internal error is related to the misra addon. you should see such error if you remove the --addon=misra also.

               
            • Georgiy Komarov

              Georgiy Komarov - 2021-06-25

              I can't reproduce this with cppcheck from the main branch (commit bf019a) too.

              Could you please provide details info about the internal error, if it appears in the closed-source code base so that we can reproduce it?

               
              • khouri

                khouri - 2021-06-28

                My colleague tried the "bf019a" version and we can confirm the issue is now fixed. Thanks for the support and apologies for the confusion. It appears that his previous build still used a version just before the relevant fixes ("e3b7ce").

                 
                👍
                1

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.