Index: lib/sanitizer_common/sanitizer_fuchsia.cc =================================================================== --- lib/sanitizer_common/sanitizer_fuchsia.cc +++ lib/sanitizer_common/sanitizer_fuchsia.cc @@ -277,14 +277,22 @@ void ReservedAddressRange::Unmap(uptr addr, uptr size) { CHECK_LE(size, size_); - if (addr == reinterpret_cast(base_)) - // If we unmap the whole range, just null out the base. - base_ = (size == size_) ? nullptr : reinterpret_cast(addr + size); - else + const zx_handle_t vmar = static_cast(os_handle_); + if (addr == reinterpret_cast(base_)) { + if (size == size_) { + // Destroying the vmar effectively unmaps the whole mapping. + _zx_vmar_destroy(vmar); + _zx_handle_close(vmar); + os_handle_ = static_cast(ZX_HANDLE_INVALID); + DecreaseTotalMmap(size); + return; + } + } else { CHECK_EQ(addr + size, reinterpret_cast(base_) + size_); - size_ -= size; - UnmapOrDieVmar(reinterpret_cast(addr), size, - static_cast(os_handle_)); + } + // Partial unmapping does not affect the fact that the initial range is still + // reserved, and the resulting unmapped memory can't be reused. + UnmapOrDieVmar(reinterpret_cast(addr), size, vmar); } // This should never be called.