From e852e41d345c4be4ca28962cbc6c6d59717759c7 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Tue, 15 Oct 2013 16:00:11 +0000 Subject: [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 --- lib/lsan/lit_tests/TestCases/pointer_to_self.cc | 18 ++++++++++++++++++ lib/lsan/lsan_common.cc | 2 ++ 2 files changed, 20 insertions(+) create mode 100644 lib/lsan/lit_tests/TestCases/pointer_to_self.cc 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 +#include + +int main() { + void *p = malloc(1337); + *reinterpret_cast(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(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; -- cgit v1.2.3