diff --git a/compiler-rt/lib/lsan/lsan_allocator.h b/compiler-rt/lib/lsan/lsan_allocator.h --- a/compiler-rt/lib/lsan/lsan_allocator.h +++ b/compiler-rt/lib/lsan/lsan_allocator.h @@ -32,6 +32,7 @@ void ForEachChunk(const Callable &callback); void GetAllocatorCacheRange(uptr *begin, uptr *end); +void AllocatorThreadStart(); void AllocatorThreadFinish(); void InitializeAllocator(); diff --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp --- a/compiler-rt/lib/lsan/lsan_allocator.cpp +++ b/compiler-rt/lib/lsan/lsan_allocator.cpp @@ -49,8 +49,11 @@ max_malloc_size = kMaxAllowedMallocSize; } +void AllocatorThreadStart() { allocator.InitCache(GetAllocatorCache()); } + void AllocatorThreadFinish() { allocator.SwallowCache(GetAllocatorCache()); + allocator.DestroyCache(GetAllocatorCache()); } static ChunkMetadata *Metadata(const void *p) { @@ -164,8 +167,14 @@ uptr GetMallocUsableSize(const void *p) { if (!p) return 0; - ChunkMetadata *m = Metadata(p); - if (!m) return 0; + void *beg = allocator.GetBlockBegin(p); + if (!beg) + return 0; + ChunkMetadata *m = Metadata(beg); + if (!m) + return 0; + if (!m->allocated) + return 0; return m->requested_size; } @@ -359,7 +368,7 @@ } SANITIZER_INTERFACE_ATTRIBUTE -uptr __sanitizer_get_free_bytes() { return 0; } +uptr __sanitizer_get_free_bytes() { return 1; } SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_unmapped_bytes() { return 0; } @@ -368,7 +377,9 @@ uptr __sanitizer_get_estimated_allocated_size(uptr size) { return size; } SANITIZER_INTERFACE_ATTRIBUTE -int __sanitizer_get_ownership(const void *p) { return Metadata(p) != nullptr; } +int __sanitizer_get_ownership(const void *p) { + return GetMallocBegin(p) != nullptr; +} SANITIZER_INTERFACE_ATTRIBUTE const void * __sanitizer_get_allocated_begin(const void *p) { @@ -380,4 +391,9 @@ return GetMallocUsableSize(p); } +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_purge_allocator() { + allocator.ForceReleaseToOS(); +} + } // extern "C" diff --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp --- a/compiler-rt/lib/lsan/lsan_thread.cpp +++ b/compiler-rt/lib/lsan/lsan_thread.cpp @@ -50,7 +50,10 @@ ThreadContextLsanBase::ThreadContextLsanBase(int tid) : ThreadContextBase(tid) {} -void ThreadContextLsanBase::OnStarted(void *arg) { SetCurrentThread(this); } +void ThreadContextLsanBase::OnStarted(void *arg) { + SetCurrentThread(this); + AllocatorThreadStart(); +} void ThreadContextLsanBase::OnFinished() { AllocatorThreadFinish(); diff --git a/compiler-rt/test/sanitizer_common/TestCases/allocator_interface.cpp b/compiler-rt/test/sanitizer_common/TestCases/allocator_interface.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/allocator_interface.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/allocator_interface.cpp @@ -5,7 +5,7 @@ // UNSUPPORTED: ubsan // FIXME: implementation is incomplete. -// XFAIL: lsan, hwasan +// XFAIL: hwasan #include #include