Bug 730580

Summary: Optimization causes memory leak
Product: [Fedora] Fedora Reporter: Susi Lehtola <susi.lehtola>
Component: cppcheckAssignee: Susi Lehtola <susi.lehtola>
Status: CLOSED CURRENTRELEASE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 15CC: jakub, susi.lehtola, ville.skytta
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-09-18 16:36:10 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Susi Lehtola 2011-08-14 15:57:54 UTC
Compilation of cppcheck-1.50-1 on Fedora 15 x86_64 with gcc-4.6.0-10.fc15.x86_64 fails in the %check phase with

TestPreprocessor:................................................................................................................................*** glibc detected *** ./testrunner: double free or corruption (out): 0x00007fff8dfaf900 ***

The problem does not occur when no optimizations are used: if one builds the program (%build phase) with CXXFLAGS="-g -O0 -DNDEBUG -DHAVE_RULES" it works, but substituting -O0 with -O2 causes the crash.

Valgrind output:

==5834== Invalid free() / delete / delete[]
==5834== at 0x4A0528C: operator delete(void*) (vg_replace_malloc.c:387)
==5834== by 0x6E7FBA: Preprocessor::getcode(std::string const&, std::string const&, std::string const&, Settings const*, ErrorLogger?*) (new_allocator.h:98)
==5834== by 0x538DE5: TestPreprocessor::invalidElIf() (testpreprocessor.cpp:2963)
==5834== by 0x55CD2F: TestPreprocessor::run() (testpreprocessor.cpp:234)
==5834== by 0x5C873F: TestFixture::run(std::string const&) (testsuite.cpp:236)
==5834== by 0x5C8C98: TestFixture::runTests(options const&) (testsuite.cpp:265)
==5834== by 0x405BA9: main (testrunner.cpp:27)
==5834== Address 0x7feffe900 is on thread 1's stack
==5834==
==5834== Invalid read of size 8
==5834== at 0x6E7FB3: Preprocessor::getcode(std::string const&, std::string const&, std::string const&, Settings const*, ErrorLogger?*) (list.tcc:74)
==5834== by 0x538DE5: TestPreprocessor::invalidElIf() (testpreprocessor.cpp:2963)
==5834== by 0x55CD2F: TestPreprocessor::run() (testpreprocessor.cpp:234)
==5834== by 0x5C873F: TestFixture::run(std::string const&) (testsuite.cpp:236)
==5834== by 0x5C8C98: TestFixture::runTests(options const&) (testsuite.cpp:265)
==5834== by 0x405BA9: main (testrunner.cpp:27)
==5834== Address 0x4c58670 is 0 bytes after a block of size 512 free'd
==5834== at 0x4A0528C: operator delete(void*) (vg_replace_malloc.c:387)
==5834== by 0x6E9A63: std::_Deque_base<std::string, std::allocator<std::string> >::~_Deque_base() (new_allocator.h:98)
==5834== by 0x6E7AF1: Preprocessor::getcode(std::string const&, std::string const&, std::string const&, Settings const*, ErrorLogger?*) (stl_deque.h:898)
==5834== by 0x538DE5: TestPreprocessor::invalidElIf() (testpreprocessor.cpp:2963)
==5834== by 0x55CD2F: TestPreprocessor::run() (testpreprocessor.cpp:234)
==5834== by 0x5C873F: TestFixture::run(std::string const&) (testsuite.cpp:236)
==5834== by 0x5C8C98: TestFixture::runTests(options const&) (testsuite.cpp:265)
==5834== by 0x405BA9: main (testrunner.cpp:27)
==5834==
==5834==
==5834== Process terminating with default action of signal 11 (SIGSEGV)
==5834== Access not within mapped region at address 0x0
==5834== at 0x6E7FB3: Preprocessor::getcode(std::string const&, std::string const&, std::string const&, Settings const*, ErrorLogger?*) (list.tcc:74)
==5834== by 0x538DE5: TestPreprocessor::invalidElIf() (testpreprocessor.cpp:2963)
==5834== by 0x55CD2F: TestPreprocessor::run() (testpreprocessor.cpp:234)
==5834== by 0x5C873F: TestFixture::run(std::string const&) (testsuite.cpp:236)
==5834== by 0x5C8C98: TestFixture::runTests(options const&) (testsuite.cpp:265)
==5834== by 0x405BA9: main (testrunner.cpp:27)
==5834== If you believe this happened as a result of a stack
==5834== overflow in your program's main thread (unlikely but
==5834== possible), you can try to increase the size of the
==5834== main thread stack using the --main-stacksize= flag.
==5834== The main thread stack size used in this run was 8388608.

Comment 1 Jakub Jelinek 2011-08-18 17:33:57 UTC
Before pointing fingers at gcc you should really try to debug the code.
This is clearly a bug in Preprocessor::getcode in preprocessor.cpp.
matching_ifdef and matched_ifdef lists there are initially empty, and if
#elif !
or
#elif 
is seen, it will happily use
matching_ifdef.back()
and/or
matched_ifdef.back()
even if matching_ifdef.empty() or matched_ifdef.empty(), but in those cases the read of that returns garbage and stores to the reference returned by back() clobber some memory around.

Comment 2 Brad Bell 2011-08-19 04:29:12 UTC
I do not know why I was added to the list for this bug. Perhaps the problem is occurring while running the tests for the cppad package (which I maintain). If so, can someone point me to the build.log file for a failed build of cppad ?

Comment 3 Jakub Jelinek 2011-08-19 06:45:18 UTC
(In reply to comment #2)
> I do not know why I was added to the list for this bug. Perhaps the problem is
> occurring while running the tests for the cppad package (which I maintain). If
> so, can someone point me to the build.log file for a failed build of cppad ?

Sorry, I just mistakenly selected cppad instead of cppcheck component.  It is now corrected, just feel free to remove yourself from CC.

Comment 4 Susi Lehtola 2011-09-18 16:36:10 UTC
Thanks Jakub. I'll be wiser next time.