mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
[vm] Fail describing errno if mmap fails for any reason except ENOMEM.
Avoids the VM later failing with a misleading "Out of Memory" message when allocation fails for lack of permission, etc. TEST=ci Bug: https://github.com/dart-lang/sdk/issues/50719 Change-Id: I52b2478092a5e5b59680f31d37ab3c6d6d816ba0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/275783 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
022ca53db3
commit
78732b243e
|
@ -54,7 +54,39 @@ DECLARE_FLAG(bool, generate_perf_jitdump);
|
|||
uword VirtualMemory::page_size_ = 0;
|
||||
VirtualMemory* VirtualMemory::compressed_heap_ = nullptr;
|
||||
|
||||
static void unmap(uword start, uword end);
|
||||
static void* Map(void* addr,
|
||||
size_t length,
|
||||
int prot,
|
||||
int flags,
|
||||
int fd,
|
||||
off_t offset) {
|
||||
void* result = mmap(addr, length, prot, flags, fd, offset);
|
||||
int error = errno;
|
||||
LOG_INFO("mmap(%p, 0x%" Px ", %u, ...): %p\n", addr, length, prot, result);
|
||||
if ((result == MAP_FAILED) && (error != ENOMEM)) {
|
||||
const int kBufferSize = 1024;
|
||||
char error_buf[kBufferSize];
|
||||
FATAL("mmap failed: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Unmap(uword start, uword end) {
|
||||
ASSERT(start <= end);
|
||||
uword size = end - start;
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (munmap(reinterpret_cast<void*>(start), size) != 0) {
|
||||
int error = errno;
|
||||
const int kBufferSize = 1024;
|
||||
char error_buf[kBufferSize];
|
||||
FATAL("munmap failed: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
static void* GenericMapAligned(void* hint,
|
||||
int prot,
|
||||
|
@ -62,9 +94,7 @@ static void* GenericMapAligned(void* hint,
|
|||
intptr_t alignment,
|
||||
intptr_t allocated_size,
|
||||
int map_flags) {
|
||||
void* address = mmap(hint, allocated_size, prot, map_flags, -1, 0);
|
||||
LOG_INFO("mmap(%p, 0x%" Px ", %u, ...): %p\n", hint, allocated_size, prot,
|
||||
address);
|
||||
void* address = Map(hint, allocated_size, prot, map_flags, -1, 0);
|
||||
if (address == MAP_FAILED) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -72,8 +102,8 @@ static void* GenericMapAligned(void* hint,
|
|||
const uword base = reinterpret_cast<uword>(address);
|
||||
const uword aligned_base = Utils::RoundUp(base, alignment);
|
||||
|
||||
unmap(base, aligned_base);
|
||||
unmap(aligned_base + size, base + allocated_size);
|
||||
Unmap(base, aligned_base);
|
||||
Unmap(aligned_base + size, base + allocated_size);
|
||||
return reinterpret_cast<void*>(aligned_base);
|
||||
}
|
||||
|
||||
|
@ -96,12 +126,12 @@ static MemoryRegion ClipToAlignedRegion(MemoryRegion region, size_t alignment) {
|
|||
region.end() >= aligned_base ? region.end() - aligned_base : 0;
|
||||
ASSERT(size_below + size_above == region.size());
|
||||
if (size_below >= size_above) {
|
||||
unmap(aligned_base, aligned_base + size_above);
|
||||
Unmap(aligned_base, aligned_base + size_above);
|
||||
return MemoryRegion(reinterpret_cast<void*>(base), size_below);
|
||||
}
|
||||
unmap(base, base + size_below);
|
||||
Unmap(base, base + size_below);
|
||||
if (size_above > alignment) {
|
||||
unmap(aligned_base + alignment, aligned_base + size_above);
|
||||
Unmap(aligned_base + alignment, aligned_base + size_above);
|
||||
size_above = alignment;
|
||||
}
|
||||
return MemoryRegion(reinterpret_cast<void*>(aligned_base), size_above);
|
||||
|
@ -231,22 +261,6 @@ bool VirtualMemory::DualMappingEnabled() {
|
|||
return FLAG_dual_map_code;
|
||||
}
|
||||
|
||||
static void unmap(uword start, uword end) {
|
||||
ASSERT(start <= end);
|
||||
uword size = end - start;
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (munmap(reinterpret_cast<void*>(start), size) != 0) {
|
||||
int error = errno;
|
||||
const int kBufferSize = 1024;
|
||||
char error_buf[kBufferSize];
|
||||
FATAL2("munmap error: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DUAL_MAPPING_SUPPORTED)
|
||||
// Do not leak file descriptors to child processes.
|
||||
#if !defined(MFD_CLOEXEC)
|
||||
|
@ -269,10 +283,9 @@ static void* MapAligned(void* hint,
|
|||
intptr_t size,
|
||||
intptr_t alignment,
|
||||
intptr_t allocated_size) {
|
||||
ASSERT(size <= allocated_size);
|
||||
void* address =
|
||||
mmap(hint, allocated_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
LOG_INFO("mmap(%p, 0x%" Px ", PROT_NONE, ...): %p\n", hint, allocated_size,
|
||||
address);
|
||||
Map(hint, allocated_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if (address == MAP_FAILED) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -283,17 +296,15 @@ static void* MapAligned(void* hint,
|
|||
// Guarantee the alignment by mapping at a fixed address inside the above
|
||||
// mapping. Overlapping region will be automatically discarded in the above
|
||||
// mapping. Manually discard non-overlapping regions.
|
||||
address = mmap(reinterpret_cast<void*>(aligned_base), size, prot,
|
||||
MAP_SHARED | MAP_FIXED, fd, 0);
|
||||
LOG_INFO("mmap(0x%" Px ", 0x%" Px ", %u, ...): %p\n", aligned_base, size,
|
||||
prot, address);
|
||||
address = Map(reinterpret_cast<void*>(aligned_base), size, prot,
|
||||
MAP_SHARED | MAP_FIXED, fd, 0);
|
||||
if (address == MAP_FAILED) {
|
||||
unmap(base, base + allocated_size);
|
||||
Unmap(base, base + allocated_size);
|
||||
return nullptr;
|
||||
}
|
||||
ASSERT(address == reinterpret_cast<void*>(aligned_base));
|
||||
unmap(base, aligned_base);
|
||||
unmap(aligned_base + size, base + allocated_size);
|
||||
Unmap(base, aligned_base);
|
||||
Unmap(aligned_base + size, base + allocated_size);
|
||||
return address;
|
||||
}
|
||||
#endif // defined(DUAL_MAPPING_SUPPORTED)
|
||||
|
@ -378,7 +389,7 @@ VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
|
|||
close(fd);
|
||||
if (alias_ptr == nullptr) {
|
||||
const uword region_base = reinterpret_cast<uword>(region_ptr);
|
||||
unmap(region_base, region_base + size);
|
||||
Unmap(region_base, region_base + size);
|
||||
return nullptr;
|
||||
}
|
||||
ASSERT(region_ptr != alias_ptr);
|
||||
|
@ -498,10 +509,10 @@ VirtualMemory::~VirtualMemory() {
|
|||
}
|
||||
#endif // defined(DART_COMPRESSED_POINTERS)
|
||||
if (vm_owns_region()) {
|
||||
unmap(reserved_.start(), reserved_.end());
|
||||
Unmap(reserved_.start(), reserved_.end());
|
||||
const intptr_t alias_offset = AliasOffset();
|
||||
if (alias_offset != 0) {
|
||||
unmap(reserved_.start() + alias_offset, reserved_.end() + alias_offset);
|
||||
Unmap(reserved_.start() + alias_offset, reserved_.end() + alias_offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -514,7 +525,7 @@ bool VirtualMemory::FreeSubSegment(void* address, intptr_t size) {
|
|||
}
|
||||
#endif // defined(DART_COMPRESSED_POINTERS)
|
||||
const uword start = reinterpret_cast<uword>(address);
|
||||
unmap(start, start + size);
|
||||
Unmap(start, start + size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -553,8 +564,8 @@ void VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
|
|||
char error_buf[kBufferSize];
|
||||
LOG_INFO("mprotect(0x%" Px ", 0x%" Px ", %u) failed\n", page_address,
|
||||
end_address - page_address, prot);
|
||||
FATAL2("mprotect error: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
FATAL("mprotect failed: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
}
|
||||
LOG_INFO("mprotect(0x%" Px ", 0x%" Px ", %u) ok\n", page_address,
|
||||
end_address - page_address, prot);
|
||||
|
@ -569,7 +580,7 @@ void VirtualMemory::DontNeed(void* address, intptr_t size) {
|
|||
int error = errno;
|
||||
const int kBufferSize = 1024;
|
||||
char error_buf[kBufferSize];
|
||||
FATAL("madvise error: %d (%s)", error,
|
||||
FATAL("madvise failed: %d (%s)", error,
|
||||
Utils::StrError(error, error_buf, kBufferSize));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue