diff options
author | Sergey Matveev <earthdok@google.com> | 2013-10-15 16:00:11 +0000 |
---|---|---|
committer | Sergey Matveev <earthdok@google.com> | 2013-10-15 16:00:11 +0000 |
commit | e852e41d345c4be4ca28962cbc6c6d59717759c7 (patch) | |
tree | 45be81918c5916bc1a44c2ec63f7d20647a26085 | |
parent | f719b92eb175f34387ef05d1c4fc1d035b94e621 (diff) | |
download | compiler-rt-e852e41d345c4be4ca28962cbc6c6d59717759c7.tar.gz compiler-rt-e852e41d345c4be4ca28962cbc6c6d59717759c7.tar.bz2 compiler-rt-e852e41d345c4be4ca28962cbc6c6d59717759c7.tar.xz |
[lsan] Fix bug when discovering indirectly leaked objects.
If an object contains pointers to itself, that doesn't make it indirectly
leaked. D'oh!
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192716 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/lsan/lit_tests/TestCases/pointer_to_self.cc | 18 | ||||
-rw-r--r-- | lib/lsan/lsan_common.cc | 2 |
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/lsan/lit_tests/TestCases/pointer_to_self.cc b/lib/lsan/lit_tests/TestCases/pointer_to_self.cc new file mode 100644 index 00000000..ecfe11b7 --- /dev/null +++ b/lib/lsan/lit_tests/TestCases/pointer_to_self.cc @@ -0,0 +1,18 @@ +// Regression test: pointers to self should not confuse LSan into thinking the +// object is indirectly leaked. Only external pointers count. +// RUN: LSAN_BASE="report_objects=1:use_registers=0" +// RUN: %clangxx_lsan %s -o %t +// RUN: LSAN_OPTIONS=$LSAN_BASE:"use_stacks=0" not %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> + +int main() { + void *p = malloc(1337); + *reinterpret_cast<void **>(p) = p; + fprintf(stderr, "Test alloc: %p.\n", p); +} +// CHECK: Test alloc: [[ADDR:.*]]. +// CHECK: Directly leaked 1337 byte object at [[ADDR]] +// CHECK: LeakSanitizer: detected memory leaks +// CHECK: SUMMARY: LeakSanitizer: diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc index a58e604f..ec914979 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cc @@ -138,6 +138,8 @@ void ScanRangeForPointers(uptr begin, uptr end, if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) continue; uptr chunk = PointsIntoChunk(p); if (!chunk) continue; + // Pointers to self don't count. This matters when tag == kIndirectlyLeaked. + if (chunk == begin) continue; LsanMetadata m(chunk); // Reachable beats ignored beats leaked. if (m.tag() == kReachable) continue; |