Menu

Valgrind/ASAN warning in Cppcheck

2024-12-28
2025-01-01
  • Andrey Alekseenko

    Running Cppcheck 1b807e1f1a9da3ad62d32ba07197e7d394f9bbd7 on the C++ source below produces a use-after-free warning from Valgrind (or, when enabled at build-time, ASan) because simplifyUsing has some overlap in token ranges for the two using expressions.

    using a = b;
    using c = d;
    
    $ valgrind ./bin/cppcheck test.cpp 
    ==722153== Memcheck, a memory error detector
    ==722153== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
    ==722153== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
    ==722153== Command: ./bin/cppcheck test.cpp
    ==722153== 
    Checking test.cpp ...
    ==722153== Invalid read of size 8
    ==722153==    at 0x20AC8E: Token::next() (token.h:900)
    ==722153==    by 0x2C5CAE: Tokenizer::simplifyUsing() (tokenize.cpp:3396)
    ==722153==    by 0x2D5EF2: Tokenizer::simplifyTokenList1(char const*) (tokenize.cpp:5739)
    ==722153==    by 0x2C6999: Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tokenize.cpp:3438)
    ==722153==    by 0x61EFCA: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1157)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153==    by 0x17EB52: CppCheckExecutor::check_internal(Settings const&) const (cppcheckexecutor.cpp:438)
    ==722153==    by 0x17E396: CppCheckExecutor::check_wrapper(Settings const&) (cppcheckexecutor.cpp:377)
    ==722153==    by 0x17E295: CppCheckExecutor::check(int, char const* const*) (cppcheckexecutor.cpp:363)
    ==722153==    by 0x14960B: main (main.cpp:90)
    ==722153==  Address 0x53d1158 is 40 bytes inside a block of size 96 free'd
    ==722153==    at 0x484C41B: operator delete(void*) (vg_replace_malloc.c:1051)
    ==722153==    by 0x80A860: Token::deletePrevious(int) (token.cpp:277)
    ==722153==    by 0x80AE29: Token::deleteThis() (token.cpp:340)
    ==722153==    by 0x2C5C9D: Tokenizer::simplifyUsing() (tokenize.cpp:3393)
    ==722153==    by 0x2D5EF2: Tokenizer::simplifyTokenList1(char const*) (tokenize.cpp:5739)
    ==722153==    by 0x2C6999: Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tokenize.cpp:3438)
    ==722153==    by 0x61EFCA: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1157)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153==    by 0x17EB52: CppCheckExecutor::check_internal(Settings const&) const (cppcheckexecutor.cpp:438)
    ==722153==    by 0x17E396: CppCheckExecutor::check_wrapper(Settings const&) (cppcheckexecutor.cpp:377)
    ==722153==    by 0x17E295: CppCheckExecutor::check(int, char const* const*) (cppcheckexecutor.cpp:363)
    ==722153==  Block was alloc'd at
    ==722153==    at 0x4848F75: operator new(unsigned long) (vg_replace_malloc.c:483)
    ==722153==    by 0x80D6BC: Token::insertToken(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::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (token.cpp:1044)
    ==722153==    by 0x830A9E: TokenList::createTokens(simplecpp::TokenList&&) (tokenlist.cpp:402)
    ==722153==    by 0x61C657: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}::operator()() const (cppcheck.cpp:1131)
    ==722153==    by 0x629491: void std::__invoke_impl<void, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&>(std::__invoke_other, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&) (invoke.h:61)
    ==722153==    by 0x628F39: std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&> >::value, void>::type std::__invoke_r<void, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&>(CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&) (invoke.h:154)
    ==722153==    by 0x628623: std::_Function_handler<void (), CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}>::_M_invoke(std::_Any_data const&) (std_function.h:290)
    ==722153==    by 0x3197AF: std::function<void ()>::operator()() const (std_function.h:590)
    ==722153==    by 0x315A7D: Timer::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, SHOWTIME_MODES, TimerResultsIntf*, std::function<void ()> const&) (timer.h:86)
    ==722153==    by 0x61ED4E: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1129)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153== 
    ==722153== Invalid read of size 8
    ==722153==    at 0x20AC8E: Token::next() (token.h:900)
    ==722153==    by 0x2C5CC7: Tokenizer::simplifyUsing() (tokenize.cpp:3397)
    ==722153==    by 0x2D5EF2: Tokenizer::simplifyTokenList1(char const*) (tokenize.cpp:5739)
    ==722153==    by 0x2C6999: Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tokenize.cpp:3438)
    ==722153==    by 0x61EFCA: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1157)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153==    by 0x17EB52: CppCheckExecutor::check_internal(Settings const&) const (cppcheckexecutor.cpp:438)
    ==722153==    by 0x17E396: CppCheckExecutor::check_wrapper(Settings const&) (cppcheckexecutor.cpp:377)
    ==722153==    by 0x17E295: CppCheckExecutor::check(int, char const* const*) (cppcheckexecutor.cpp:363)
    ==722153==    by 0x14960B: main (main.cpp:90)
    ==722153==  Address 0x53d1158 is 40 bytes inside a block of size 96 free'd
    ==722153==    at 0x484C41B: operator delete(void*) (vg_replace_malloc.c:1051)
    ==722153==    by 0x80A860: Token::deletePrevious(int) (token.cpp:277)
    ==722153==    by 0x80AE29: Token::deleteThis() (token.cpp:340)
    ==722153==    by 0x2C5C9D: Tokenizer::simplifyUsing() (tokenize.cpp:3393)
    ==722153==    by 0x2D5EF2: Tokenizer::simplifyTokenList1(char const*) (tokenize.cpp:5739)
    ==722153==    by 0x2C6999: Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (tokenize.cpp:3438)
    ==722153==    by 0x61EFCA: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1157)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153==    by 0x17EB52: CppCheckExecutor::check_internal(Settings const&) const (cppcheckexecutor.cpp:438)
    ==722153==    by 0x17E396: CppCheckExecutor::check_wrapper(Settings const&) (cppcheckexecutor.cpp:377)
    ==722153==    by 0x17E295: CppCheckExecutor::check(int, char const* const*) (cppcheckexecutor.cpp:363)
    ==722153==  Block was alloc'd at
    ==722153==    at 0x4848F75: operator new(unsigned long) (vg_replace_malloc.c:483)
    ==722153==    by 0x80D6BC: Token::insertToken(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::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool) (token.cpp:1044)
    ==722153==    by 0x830A9E: TokenList::createTokens(simplecpp::TokenList&&) (tokenlist.cpp:402)
    ==722153==    by 0x61C657: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}::operator()() const (cppcheck.cpp:1131)
    ==722153==    by 0x629491: void std::__invoke_impl<void, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&>(std::__invoke_other, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&) (invoke.h:61)
    ==722153==    by 0x628F39: std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&> >::value, void>::type std::__invoke_r<void, CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&>(CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}&) (invoke.h:154)
    ==722153==    by 0x628623: std::_Function_handler<void (), CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*)::{lambda()#4}>::_M_invoke(std::_Any_data const&) (std_function.h:290)
    ==722153==    by 0x3197AF: std::function<void ()>::operator()() const (std_function.h:590)
    ==722153==    by 0x315A7D: Timer::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, SHOWTIME_MODES, TimerResultsIntf*, std::function<void ()> const&) (timer.h:86)
    ==722153==    by 0x61ED4E: CppCheck::checkFile(FileWithDetails const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream*) (cppcheck.cpp:1129)
    ==722153==    by 0x61B88F: CppCheck::check(FileWithDetails const&) (cppcheck.cpp:776)
    ==722153==    by 0x1ACE75: SingleExecutor::check() (singleexecutor.cpp:53)
    ==722153== 
    ==722153== 
    ==722153== HEAP SUMMARY:
    ==722153==     in use at exit: 0 bytes in 0 blocks
    ==722153==   total heap usage: 27,050 allocs, 27,050 frees, 4,449,911 bytes allocated
    ==722153== 
    ==722153== All heap blocks were freed -- no leaks are possible
    ==722153== 
    ==722153== For lists of detected and suppressed errors, rerun with: -s
    
     
  • Oliver Stöneberg

    A ticket was filed about this: https://trac.cppcheck.net/ticket/13492 (and already fixed).

     
  • Andrey Alekseenko

    Amazing, thanks!

     

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.