summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortimurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 12:54:44 +0000
committertimurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 12:54:44 +0000
commit9ded99137e5ada1d9fbeeee8632f3a825f3c4498 (patch)
tree8a2645eabef077ec85894b281c3e96b1c81c2fb8
parenta10d16e53eac4afba30c05ff56911576be2c569e (diff)
downloadchromium_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.cc68
-rwxr-xr-xtools/valgrind/memcheck/suppressions.txt80
-rwxr-xr-xtools/valgrind/memcheck_analyze.py27
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: