Index: compiler-rt/trunk/lib/asan/asan_mac.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_mac.cc +++ compiler-rt/trunk/lib/asan/asan_mac.cc @@ -62,16 +62,36 @@ uptr space_size = kHighShadowEnd + left_padding; uptr largest_gap_found = 0; - uptr shadow_start = FindAvailableMemoryRange(space_size, alignment, - granularity, &largest_gap_found); + uptr max_occupied_addr = 0; + VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size); + uptr shadow_start = + FindAvailableMemoryRange(space_size, alignment, granularity, + &largest_gap_found, &max_occupied_addr); // If the shadow doesn't fit, restrict the address space to make it fit. if (shadow_start == 0) { + VReport( + 2, + "Shadow doesn't fit, largest_gap_found = %p, max_occupied_addr = %p\n", + largest_gap_found, max_occupied_addr); uptr new_max_vm = RoundDownTo(largest_gap_found << SHADOW_SCALE, alignment); + if (new_max_vm < max_occupied_addr) { + Report("Unable to find a memory range for dynamic shadow.\n"); + Report( + "space_size = %p, largest_gap_found = %p, max_occupied_addr = %p, " + "new_max_vm = %p\n", + space_size, largest_gap_found, max_occupied_addr, new_max_vm); + CHECK(0 && "cannot place shadow"); + } RestrictMemoryToMaxAddress(new_max_vm); kHighMemEnd = new_max_vm - 1; space_size = kHighShadowEnd + left_padding; - shadow_start = - FindAvailableMemoryRange(space_size, alignment, granularity, nullptr); + VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size); + shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity, + nullptr, nullptr); + if (shadow_start == 0) { + Report("Unable to find a memory range after restricting VM.\n"); + CHECK(0 && "cannot place shadow after restricting vm"); + } } CHECK_NE((uptr)0, shadow_start); CHECK(IsAligned(shadow_start, alignment)); Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h @@ -112,7 +112,7 @@ // Find an available address space. uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found); + uptr *largest_gap_found, uptr *max_occupied_addr); // Used to check if we can map shadow memory to a fixed location. bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc @@ -1859,7 +1859,8 @@ } uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found) { + uptr *largest_gap_found, + uptr *max_occupied_addr) { UNREACHABLE("FindAvailableMemoryRange is not available"); return 0; } Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc @@ -887,10 +887,9 @@ return GetMaxUserVirtualAddress(); } -uptr FindAvailableMemoryRange(uptr shadow_size, - uptr alignment, - uptr left_padding, - uptr *largest_gap_found) { +uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, + uptr *largest_gap_found, + uptr *max_occupied_addr) { typedef vm_region_submap_short_info_data_64_t RegionInfo; enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 }; // Start searching for available memory region past PAGEZERO, which is @@ -902,6 +901,7 @@ mach_vm_address_t free_begin = start_address; kern_return_t kr = KERN_SUCCESS; if (largest_gap_found) *largest_gap_found = 0; + if (max_occupied_addr) *max_occupied_addr = 0; while (kr == KERN_SUCCESS) { mach_vm_size_t vmsize = 0; natural_t depth = 0; @@ -913,13 +913,15 @@ // No more regions beyond "address", consider the gap at the end of VM. address = GetMaxVirtualAddress() + 1; vmsize = 0; + } else { + if (max_occupied_addr) *max_occupied_addr = address + vmsize; } if (free_begin != address) { // We found a free region [free_begin..address-1]. uptr gap_start = RoundUpTo((uptr)free_begin + left_padding, alignment); uptr gap_end = RoundDownTo((uptr)address, alignment); uptr gap_size = gap_end > gap_start ? gap_end - gap_start : 0; - if (shadow_size < gap_size) { + if (size < gap_size) { return gap_start; } Index: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc =================================================================== --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc @@ -331,7 +331,8 @@ } uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found) { + uptr *largest_gap_found, + uptr *max_occupied_addr) { uptr address = 0; while (true) { MEMORY_BASIC_INFORMATION info;