Index: compiler-rt/lib/lsan/lsan_common_mac.cpp =================================================================== --- compiler-rt/lib/lsan/lsan_common_mac.cpp +++ compiler-rt/lib/lsan/lsan_common_mac.cpp @@ -27,8 +27,10 @@ // Only introduced in Mac OS X 10.9. #ifdef VM_MEMORY_OS_ALLOC_ONCE static const int kSanitizerVmMemoryOsAllocOnce = VM_MEMORY_OS_ALLOC_ONCE; +static const int kSanitizerVmMemoryLibdispatch = VM_MEMORY_LIBDISPATCH; #else static const int kSanitizerVmMemoryOsAllocOnce = 73; +static const int kSanitizerVmMemoryLibdispatch = 74; #endif namespace __lsan { @@ -148,6 +150,8 @@ InternalMmapVectorNoCtor const *root_regions = GetRootRegions(); + bool saw_alloc_once = false; + bool saw_libdispatch = false; while (err == KERN_SUCCESS) { vm_size_t size = 0; unsigned depth = 1; @@ -157,19 +161,26 @@ (vm_region_info_t)&info, &count); uptr end_address = address + size; - - // libxpc stashes some pointers in the Kernel Alloc Once page, - // make sure not to report those as leaks. + bool scan_region = false; if (info.user_tag == kSanitizerVmMemoryOsAllocOnce) { + scan_region = true; + saw_alloc_once = true; + } else if (info.user_tag == kSanitizerVmMemoryLibdispatch) { + scan_region = true; + saw_libdispatch = true; + } + + if (scan_region) { ScanRangeForPointers(address, end_address, frontier, "GLOBAL", kReachable); - - // Recursing over the full memory map is very slow, break out - // early if we don't need the full iteration. - if (!flags()->use_root_regions || !root_regions->size()) - break; } + // Recursing over the full memory map is very slow, break out + // early if we don't need the full iteration. + if (saw_alloc_once && saw_libdispatch && + (flags()->use_root_regions || !root_regions->size())) + break; + // This additional root region scan is required on Darwin in order to // detect root regions contained within mmap'd memory regions, because // the Darwin implementation of sanitizer_procmaps traverses images