diff options
author | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 12:54:44 +0000 |
---|---|---|
committer | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 12:54:44 +0000 |
commit | 9ded99137e5ada1d9fbeeee8632f3a825f3c4498 (patch) | |
tree | 8a2645eabef077ec85894b281c3e96b1c81c2fb8 | |
parent | a10d16e53eac4afba30c05ff56911576be2c569e (diff) | |
download | chromium_src-9ded99137e5ada1d9fbeeee8632f3a825f3c4498.zip chromium_src-9ded99137e5ada1d9fbeeee8632f3a825f3c4498.tar.gz chromium_src-9ded99137e5ada1d9fbeeee8632f3a825f3c4498.tar.bz2 |
Implement more sanity tests for Memcheck/Valgrind
Review URL: http://codereview.chromium.org/1242008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42751 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/tools_sanity_unittest.cc | 68 | ||||
-rwxr-xr-x | tools/valgrind/memcheck/suppressions.txt | 80 | ||||
-rwxr-xr-x | tools/valgrind/memcheck_analyze.py | 27 |
3 files changed, 170 insertions, 5 deletions
diff --git a/base/tools_sanity_unittest.cc b/base/tools_sanity_unittest.cc index 0a18031..f4d4df9 100644 --- a/base/tools_sanity_unittest.cc +++ b/base/tools_sanity_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/dynamic_annotations.h" #include "base/message_loop.h" #include "base/thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,7 +24,7 @@ class TOOLS_SANITY_TEST_CONCURRENT_THREAD : public PlatformThread::Delegate { PlatformThread::Sleep(100); } private: - bool* value_; + bool *value_; }; } @@ -34,6 +35,71 @@ TEST(ToolsSanityTest, MemoryLeak) { leak[4] = 1; // Make sure the allocated memory is used. } +void ReadValueOutOfArrayBoundsLeft(char *ptr) { + LOG(INFO) << "Reading a byte out of bounds: " << ptr[-2]; +} + +void ReadValueOutOfArrayBoundsRight(char *ptr, size_t size) { + LOG(INFO) << "Reading a byte out of bounds: " << ptr[size + 1]; +} + +// This is harmless if you run it under Valgrind thanks to redzones. +void WriteValueOutOfArrayBoundsLeft(char *ptr) { + ptr[-1] = 42; +} + +// This is harmless if you run it under Valgrind thanks to redzones. +void WriteValueOutOfArrayBoundsRight(char *ptr, size_t size) { + ptr[size] = 42; +} + +void MakeSomeErrors(char *ptr, size_t size) { + ReadValueOutOfArrayBoundsLeft(ptr); + ReadValueOutOfArrayBoundsRight(ptr, size); + WriteValueOutOfArrayBoundsLeft(ptr); + WriteValueOutOfArrayBoundsRight(ptr, size); +} + +TEST(ToolsSanityTest, AccessesToNewMemory) { + // This test may corrupt memory if not run under Valgrind. + if (!RunningOnValgrind()) + return; + + char *foo = new char[10]; + MakeSomeErrors(foo, 10); + delete [] foo; + foo[5] = 0; // Use after delete. This won't break anything under Valgrind. +} + +TEST(ToolsSanityTest, AccessesToMallocMemory) { + // This test may corrupt memory if not run under Valgrind. + if (!RunningOnValgrind()) + return; + + char *foo = reinterpret_cast<char*>(malloc(10)); + MakeSomeErrors(foo, 10); + free(foo); + foo[5] = 0; // Use after free. This won't break anything under Valgrind. +} + +TEST(ToolsSanityTest, ArrayDeletedWithoutBraces) { + // This test may corrupt memory if not run under Valgrind. + if (!RunningOnValgrind()) + return; + + int *foo = new int[10]; + delete foo; +} + +TEST(ToolsSanityTest, SingleElementDeletedWithBraces) { + // This test may corrupt memory if not run under Valgrind. + if (!RunningOnValgrind()) + return; + + int *foo = new int; + delete [] foo; +} + // A data race detector should report an error in this test. TEST(ToolsSanityTest, DataRace) { bool shared = false; diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index 754395c..1e34f07 100755 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt @@ -459,12 +459,90 @@ # 2. intentional unit test errors, or stuff that is somehow a false positive # in our own code, or stuff that is so trivial it's not worth fixing { - Memcheck sanity test (ToolsSanityTest.MemoryLeak). + Memcheck sanity test (memory leak). Memcheck:Leak fun:_Zna* fun:_ZN31ToolsSanityTest_MemoryLeak_Test8TestBodyEv } { + Memcheck sanity test (malloc/read left). + Memcheck:Addr1 + fun:_Z29ReadValueOutOfArrayBoundsLeftPc + fun:_Z14MakeSomeErrorsPc* + fun:_ZN43ToolsSanityTest_AccessesToMallocMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (malloc/read right). + Memcheck:Addr1 + fun:_Z30ReadValueOutOfArrayBoundsRightPc* + fun:_Z14MakeSomeErrorsPc* + fun:_ZN43ToolsSanityTest_AccessesToMallocMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (malloc/write left). + Memcheck:Addr1 + fun:_Z30WriteValueOutOfArrayBoundsLeftPc + fun:_Z14MakeSomeErrorsPc* + fun:_ZN43ToolsSanityTest_AccessesToMallocMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (malloc/write right). + Memcheck:Addr1 + fun:_Z31WriteValueOutOfArrayBoundsRightPc* + fun:_Z14MakeSomeErrorsPc* + fun:_ZN43ToolsSanityTest_AccessesToMallocMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (new/read left). + Memcheck:Addr1 + fun:_Z29ReadValueOutOfArrayBoundsLeftPc + fun:_Z14MakeSomeErrorsPc* + fun:_ZN40ToolsSanityTest_AccessesToNewMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (new/read right). + Memcheck:Addr1 + fun:_Z30ReadValueOutOfArrayBoundsRightPc* + fun:_Z14MakeSomeErrorsPc* + fun:_ZN40ToolsSanityTest_AccessesToNewMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (new/write left). + Memcheck:Addr1 + fun:_Z30WriteValueOutOfArrayBoundsLeftPc + fun:_Z14MakeSomeErrorsPc* + fun:_ZN40ToolsSanityTest_AccessesToNewMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (new/write right). + Memcheck:Addr1 + fun:_Z31WriteValueOutOfArrayBoundsRightPc* + fun:_Z14MakeSomeErrorsPc* + fun:_ZN40ToolsSanityTest_AccessesToNewMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (write after free). + Memcheck:Addr1 + fun:_ZN43ToolsSanityTest_AccessesToMallocMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (write after delete). + Memcheck:Addr1 + fun:_ZN40ToolsSanityTest_AccessesToNewMemory_Test8TestBodyEv +} +{ + Memcheck sanity test (array deleted without []). + Memcheck:Free + ... + fun:_ZN46ToolsSanityTest_ArrayDeletedWithoutBraces_Test8TestBodyEv +} +{ + Memcheck sanity test (single element deleted with []). + Memcheck:Free + ... + fun:_ZN51ToolsSanityTest_SingleElementDeletedWithBraces_Test8TestBodyEv +} +{ logging::InitLogging never frees filename. It would be hard to free properly. Memcheck:Leak ... diff --git a/tools/valgrind/memcheck_analyze.py b/tools/valgrind/memcheck_analyze.py index c70df99..41bf4da 100755 --- a/tools/valgrind/memcheck_analyze.py +++ b/tools/valgrind/memcheck_analyze.py @@ -311,7 +311,22 @@ class MemcheckAnalyze: ''' Given a set of Valgrind XML files, parse all the errors out of them, unique them and output the results.''' - SANITY_TEST_SUPPRESSION = "Memcheck sanity test" + SANITY_TEST_SUPPRESSIONS = [ + "Memcheck sanity test (array deleted without []).", + "Memcheck sanity test (malloc/read left).", + "Memcheck sanity test (malloc/read right).", + "Memcheck sanity test (malloc/write left).", + "Memcheck sanity test (malloc/write right).", + "Memcheck sanity test (memory leak).", + "Memcheck sanity test (new/read left).", + "Memcheck sanity test (new/read right).", + "Memcheck sanity test (new/write left).", + "Memcheck sanity test (new/write right).", + "Memcheck sanity test (single element deleted with []).", + "Memcheck sanity test (write after delete).", + "Memcheck sanity test (write after free).", + ] + def __init__(self, source_dir, files, show_all_leaks=False, use_gdb=False): '''Reads in a set of files. @@ -439,10 +454,13 @@ class MemcheckAnalyze: print "-----------------------------------------------------" print "Suppressions used:" print " count name" + remaining_sanity_supp = set(MemcheckAnalyze.SANITY_TEST_SUPPRESSIONS) for item in sorted(self._suppcounts.items(), key=lambda (k,v): (v,k)): print "%7s %s" % (item[1], item[0]) - if item[0].startswith(MemcheckAnalyze.SANITY_TEST_SUPPRESSION): - is_sane = True + if item[0] in remaining_sanity_supp: + remaining_sanity_supp.remove(item[0]) + if len(remaining_sanity_supp) == 0: + is_sane = True print "-----------------------------------------------------" sys.stdout.flush() @@ -462,6 +480,9 @@ class MemcheckAnalyze: # Report tool's insanity even if there were errors. if check_sanity and not is_sane: logging.error("FAIL! Sanity check failed!") + logging.info("The following test errors were not handled: ") + for supp in remaining_sanity_supp: + logging.info(" " + supp) retcode = -3 if retcode != 0: |