Menu

Segmentation Fault when analyzing C11 Generic

2023-12-08
2024-01-25
  • Tobias Specht

    Tobias Specht - 2023-12-08

    Hi,

    when analyzing the following C11 code, cppcheck crashes with a segmentation fault:

    void func_a(int *a) {
    }
    
    void func_b(float *b) {
    }
    
    #define foo(i) _Generic((i), \
      int*:func_a,  \
      float*:func_b \
      )(i)
    
    int main(int argc, char argv[]) {
      int bar;
    
      if (0 != argc) {
        foo(&bar);
      }
      return 0;
    }
    
    $ gcc main.c
    $ ./a.out
    $ cppcheck --version
    Cppcheck 2.12.1
    $ cppcheck  main.c
    Checking main.c ...
    Segmentation fault (core dumped)
    

    The bug seems to be related to the C11 generic function in combination with the condition.
    Calling a generic function outside the condition is not a problem.
    Interestingly, the crash does not occur (at least not on my machine) when the condition is == instead of !=.
    The POC is valid C11 code and compiles fine.

    Can you reproduce this bug?

    Best regards,
    Tobias

     
  • CHR

    CHR - 2023-12-08

    Seems to have been fixed in head around Sep/Oct.

     
  • Tobias Specht

    Tobias Specht - 2023-12-08

    Thanks for your answer.
    Then it must be just after the last release.
    Compiling from main fixes the problem for me.

     
  • Oliver Stöneberg

    Here's the stacktrace:

    ==3997== Process terminating with default action of signal 11 (SIGSEGV)
    ==3997==  Access not within mapped region at address 0x50
    ==3997==    at 0x319977: Token const* getTokenArgumentFunctionImpl<Token const, void>(Token const*, int&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x31145F: getParentValueTypes(Token const*, Settings const*, Token const**) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x312446: isUsedAsBool(Token const*, Settings const*) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x316951: isSameExpression(bool, bool, Token const*, Token const*, Library const&, bool, bool, std::__cxx11::list<std::pair<Token const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<Token const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >*) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x2425D4: SameExpressionAnalyzer::match(Token const*) const (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x254D98: ValueFlowAnalyzer::analyzeToken(Token const*, Token const*, Analyzer::Direction, bool) const (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x2551DD: ValueFlowAnalyzer::analyze(Token const*, Analyzer::Direction) const (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x47C4DA: ForwardTraversal::Progress ForwardTraversal::traverseTok<Token, ForwardTraversal::updateTok(Token*, Token**)::{lambda(Token*)#1}, void>(Token*, ForwardTraversal::updateTok(Token*, Token**)::{lambda(Token*)#1}, bool, Token**) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x478AAB: ForwardTraversal::updateRange(Token*, Token const*, int) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x47510D: valueFlowGenericForward(Token*, Token const*, ValuePtr<Analyzer> const&, Settings const&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x20D2AA: valueFlowConditionExpressions(TokenList&, SymbolDatabase const&, ErrorLogger*, Settings const&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x244BD5: ValueFlowPassRunner::run(ValuePtr<ValueFlowPass> const&) const (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x20F708: ValueFlow::setValues(TokenList&, SymbolDatabase&, ErrorLogger*, Settings const*, TimerResultsIntf*) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x2B6CB2: Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x44CD19: CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x44E8AB: CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x552054: SingleExecutor::check() (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x540B7E: CppCheckExecutor::check_internal(CppCheck&) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x5458F0: CppCheckExecutor::check(int, char const* const*) (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    ==3997==    by 0x1CCDCF: main (in /home/sshuser/.bisect/ad4e688ff/cppcheck)
    

    This started with 2.10 and has been bisected to https://github.com/danmar/cppcheck/commit/117a753b1006a1116829f053a1c8e3912e22bde1.

    This was fixed in 2.13.0 and the fix has indeed been bisected to https://github.com/danmar/cppcheck/commit/dd76504f8289289e942cae5f52dd63b8617f118a.

    This is really curious and should be looked into.

     
  • CHR

    CHR - 2024-01-24

    The crash happened on a , without astOperand1(). The AST is still broken.
    The crash is currently avoided by a bailout in valueFlowConditionExpressions():
    if (const Token* incompleteTok = findIncompleteVar(scope->bodyStart, scope->bodyEnd)) ... break;

     
    • CHR

      CHR - 2024-01-24

      That seems to have been the situation right after the fix. Nowadays the crash is prevented by the second condition in if (!Token::Match(parent, "%cop%") && !(parent->str() == "(" && tok == parent->astOperand1())) in isUsedAsBool().

       
  • CHR

    CHR - 2024-01-25
     

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.