forked from OSchip/llvm-project
[Asan] Fix false leak report
If user thread is in the allocator, the allocator may have no pointer into future user's part of the allocated block. AddrIsInside ignores such pointers and lsan reports a false memory leak. Reviewed By: morehouse Differential Revision: https://reviews.llvm.org/D87552
This commit is contained in:
parent
c2590de30d
commit
9d01612db4
|
@ -1111,19 +1111,17 @@ void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
|
||||||
*end = *begin + sizeof(__asan::get_allocator());
|
*end = *begin + sizeof(__asan::get_allocator());
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr PointsIntoChunk(void* p) {
|
uptr PointsIntoChunk(void *p) {
|
||||||
uptr addr = reinterpret_cast<uptr>(p);
|
uptr addr = reinterpret_cast<uptr>(p);
|
||||||
__asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);
|
__asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);
|
||||||
if (!m || atomic_load(&m->chunk_state, memory_order_acquire) !=
|
if (!m || atomic_load(&m->chunk_state, memory_order_acquire) !=
|
||||||
__asan::CHUNK_ALLOCATED)
|
__asan::CHUNK_ALLOCATED)
|
||||||
return 0;
|
return 0;
|
||||||
uptr chunk = m->Beg();
|
// AsanChunk presence means that we point into some block from underlying
|
||||||
if (m->AddrIsInside(addr, /*locked_version=*/true))
|
// allocators. Don't check whether p points into user memory, since until
|
||||||
return chunk;
|
// the return from AsanAllocator::Allocator we may have no such
|
||||||
if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),
|
// pointer anywhere. But we must already have a pointer to GetBlockBegin().
|
||||||
addr))
|
return m->Beg();
|
||||||
return chunk;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uptr GetUserBegin(uptr chunk) {
|
uptr GetUserBegin(uptr chunk) {
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Test whether pointers into left redzone count memory are reachable.
|
||||||
|
// If user thread is inside asan allocator code then we may have no
|
||||||
|
// pointers into user part of memory yet. However we should have a pointer
|
||||||
|
// into the allocated memory chunk.
|
||||||
|
//
|
||||||
|
// RUN: %clangxx_asan %s -o %t
|
||||||
|
// RUN: %run %t 2>&1
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
void *pointers[1000];
|
||||||
|
void **cur = pointers;
|
||||||
|
|
||||||
|
void leak(int n, int offset) {
|
||||||
|
printf("%d %d\n", n, offset);
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
*(cur++) = (new int[n]) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
for (int n = 1; n < 10000000; n = n * 2) {
|
||||||
|
leak(n, 0);
|
||||||
|
leak(n, -1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue