diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2021-11-12 22:23:45 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2021-11-13 05:15:24 -0800 |
commit | 86289a4ff4768fab61f16372650fe85c37f9284e (patch) | |
tree | 4e2328cbff3a90cb8739f7e6fd95621d8aa16789 /libsanitizer/lsan | |
parent | a30a2e43e4a357919ecfa916451966f8e32b5176 (diff) | |
download | gcc-86289a4ff4768fab61f16372650fe85c37f9284e.zip gcc-86289a4ff4768fab61f16372650fe85c37f9284e.tar.gz gcc-86289a4ff4768fab61f16372650fe85c37f9284e.tar.bz2 |
libsanitizer: Merge with upstream
Merged revision: 82bc6a094e85014f1891ef9407496f44af8fe442
with the fix for PR sanitizer/102911
Diffstat (limited to 'libsanitizer/lsan')
-rw-r--r-- | libsanitizer/lsan/lsan_common.cpp | 31 | ||||
-rw-r--r-- | libsanitizer/lsan/lsan_common.h | 9 | ||||
-rw-r--r-- | libsanitizer/lsan/lsan_common_mac.cpp | 2 | ||||
-rw-r--r-- | libsanitizer/lsan/lsan_interceptors.cpp | 44 |
4 files changed, 47 insertions, 39 deletions
diff --git a/libsanitizer/lsan/lsan_common.cpp b/libsanitizer/lsan/lsan_common.cpp index 139abd0..308dbb3 100644 --- a/libsanitizer/lsan/lsan_common.cpp +++ b/libsanitizer/lsan/lsan_common.cpp @@ -131,18 +131,13 @@ static LeakSuppressionContext *GetSuppressionContext() { return suppression_ctx; } -static InternalMmapVector<RootRegion> *root_regions; +static InternalMmapVectorNoCtor<RootRegion> root_regions; -InternalMmapVector<RootRegion> const *GetRootRegions() { return root_regions; } - -void InitializeRootRegions() { - CHECK(!root_regions); - ALIGNED(64) static char placeholder[sizeof(InternalMmapVector<RootRegion>)]; - root_regions = new (placeholder) InternalMmapVector<RootRegion>(); +InternalMmapVectorNoCtor<RootRegion> const *GetRootRegions() { + return &root_regions; } void InitCommonLsan() { - InitializeRootRegions(); if (common_flags()->detect_leaks) { // Initialization which can fail or print warnings should only be done if // LSan is actually enabled. @@ -426,10 +421,8 @@ static void ProcessRootRegion(Frontier *frontier, // Scans root regions for heap pointers. static void ProcessRootRegions(Frontier *frontier) { if (!flags()->use_root_regions) return; - CHECK(root_regions); - for (uptr i = 0; i < root_regions->size(); i++) { - ProcessRootRegion(frontier, (*root_regions)[i]); - } + for (uptr i = 0; i < root_regions.size(); i++) + ProcessRootRegion(frontier, root_regions[i]); } static void FloodFillTag(Frontier *frontier, ChunkTag tag) { @@ -966,9 +959,8 @@ SANITIZER_INTERFACE_ATTRIBUTE void __lsan_register_root_region(const void *begin, uptr size) { #if CAN_SANITIZE_LEAKS Lock l(&global_mutex); - CHECK(root_regions); RootRegion region = {reinterpret_cast<uptr>(begin), size}; - root_regions->push_back(region); + root_regions.push_back(region); VReport(1, "Registered root region at %p of size %zu\n", begin, size); #endif // CAN_SANITIZE_LEAKS } @@ -977,15 +969,14 @@ SANITIZER_INTERFACE_ATTRIBUTE void __lsan_unregister_root_region(const void *begin, uptr size) { #if CAN_SANITIZE_LEAKS Lock l(&global_mutex); - CHECK(root_regions); bool removed = false; - for (uptr i = 0; i < root_regions->size(); i++) { - RootRegion region = (*root_regions)[i]; + for (uptr i = 0; i < root_regions.size(); i++) { + RootRegion region = root_regions[i]; if (region.begin == reinterpret_cast<uptr>(begin) && region.size == size) { removed = true; - uptr last_index = root_regions->size() - 1; - (*root_regions)[i] = (*root_regions)[last_index]; - root_regions->pop_back(); + uptr last_index = root_regions.size() - 1; + root_regions[i] = root_regions[last_index]; + root_regions.pop_back(); VReport(1, "Unregistered root region at %p of size %zu\n", begin, size); break; } diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h index 93b7d4e..f9b55e4 100644 --- a/libsanitizer/lsan/lsan_common.h +++ b/libsanitizer/lsan/lsan_common.h @@ -140,7 +140,7 @@ struct CheckForLeaksParam { bool success = false; }; -InternalMmapVector<RootRegion> const *GetRootRegions(); +InternalMmapVectorNoCtor<RootRegion> const *GetRootRegions(); void ScanRootRegion(Frontier *frontier, RootRegion const ®ion, uptr region_begin, uptr region_end, bool is_readable); void ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg); @@ -280,6 +280,13 @@ int __lsan_is_turned_off(); SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char *__lsan_default_suppressions(); + +SANITIZER_INTERFACE_ATTRIBUTE +void __lsan_register_root_region(const void *p, __lsan::uptr size); + +SANITIZER_INTERFACE_ATTRIBUTE +void __lsan_unregister_root_region(const void *p, __lsan::uptr size); + } // extern "C" #endif // LSAN_COMMON_H diff --git a/libsanitizer/lsan/lsan_common_mac.cpp b/libsanitizer/lsan/lsan_common_mac.cpp index 8516a17..4301dcc 100644 --- a/libsanitizer/lsan/lsan_common_mac.cpp +++ b/libsanitizer/lsan/lsan_common_mac.cpp @@ -149,7 +149,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) { kern_return_t err = KERN_SUCCESS; mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; - InternalMmapVector<RootRegion> const *root_regions = GetRootRegions(); + InternalMmapVectorNoCtor<RootRegion> const *root_regions = GetRootRegions(); while (err == KERN_SUCCESS) { struct vm_region_submap_info_64 info; diff --git a/libsanitizer/lsan/lsan_interceptors.cpp b/libsanitizer/lsan/lsan_interceptors.cpp index 90a90a5..22999d5 100644 --- a/libsanitizer/lsan/lsan_interceptors.cpp +++ b/libsanitizer/lsan/lsan_interceptors.cpp @@ -13,6 +13,7 @@ #include "interception/interception.h" #include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_allocator_dlsym.h" #include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" @@ -43,6 +44,22 @@ int pthread_key_create(unsigned *key, void (*destructor)(void* v)); int pthread_setspecific(unsigned key, const void *v); } +struct DlsymAlloc : DlSymAllocator<DlsymAlloc> { + static bool UseImpl() { return lsan_init_is_running; } + static void OnAllocate(const void *ptr, uptr size) { +#if CAN_SANITIZE_LEAKS + // Suppress leaks from dlerror(). Previously dlsym hack on global array was + // used by leak sanitizer as a root region. + __lsan_register_root_region(ptr, size); +#endif + } + static void OnFree(const void *ptr, uptr size) { +#if CAN_SANITIZE_LEAKS + __lsan_unregister_root_region(ptr, size); +#endif + } +}; + ///// Malloc/free interceptors. ///// namespace std { @@ -52,41 +69,34 @@ namespace std { #if !SANITIZER_MAC INTERCEPTOR(void*, malloc, uptr size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Allocate(size); ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; return lsan_malloc(size, stack); } INTERCEPTOR(void, free, void *p) { + if (DlsymAlloc::PointerIsMine(p)) + return DlsymAlloc::Free(p); ENSURE_LSAN_INITED; lsan_free(p); } INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { - // This hack is not required for Fuchsia because there are no dlsym calls - // involved in setting up interceptors. -#if !SANITIZER_FUCHSIA - if (lsan_init_is_running) { - // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. - const uptr kCallocPoolSize = 1024; - static uptr calloc_memory_for_dlsym[kCallocPoolSize]; - static uptr allocated; - uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; - void *mem = (void*)&calloc_memory_for_dlsym[allocated]; - allocated += size_in_words; - CHECK(allocated < kCallocPoolSize); - return mem; - } -#endif // !SANITIZER_FUCHSIA + if (DlsymAlloc::Use()) + return DlsymAlloc::Callocate(nmemb, size); ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; return lsan_calloc(nmemb, size, stack); } -INTERCEPTOR(void*, realloc, void *q, uptr size) { +INTERCEPTOR(void *, realloc, void *ptr, uptr size) { + if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Realloc(ptr, size); ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; - return lsan_realloc(q, size, stack); + return lsan_realloc(ptr, size, stack); } INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) { |