Summary:
The previous version assumed that `RegionSize` would always be the full size of the allocation done by `VirtualAlloc`. However, `RegionSize` actually only includes the following pages that have the same attributes, so, if you change the access permissions via `mprotect`, the `RegionSize` would exclude that region, which is not what was intended.
This instead stores the length and a dummy magic value after the end of the requested allocation.
Reviewed By: yfeldblum
Differential Revision:
D3812949
fbshipit-source-id:
53bbbcc371accbed08adaffa82fc082ec44f316f
+namespace {
+constexpr uint32_t kMMapLengthMagic = 0xFACEB00C;
+struct MemMapDebugTrailer {
+ size_t length;
+ uint32_t magic;
+};
+}
+
void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) {
// Make sure it's something we support first.
void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) {
// Make sure it's something we support first.
}
CloseHandle(fmh);
} else {
}
CloseHandle(fmh);
} else {
+ auto baseLength = length;
+ if (folly::kIsDebug) {
+ // In debug mode we keep track of the length to make
+ // sure you're only munmapping the entire thing if
+ // we're using VirtualAlloc.
+ length += sizeof(MemMapDebugTrailer);
+ }
+
// VirtualAlloc rounds size down to a multiple
// of the system allocation granularity :(
length = alignToAllocationGranularity(length);
// VirtualAlloc rounds size down to a multiple
// of the system allocation granularity :(
length = alignToAllocationGranularity(length);
if (ret == nullptr) {
return MAP_FAILED;
}
if (ret == nullptr) {
return MAP_FAILED;
}
+
+ if (folly::kIsDebug) {
+ auto deb = (MemMapDebugTrailer*)((char*)ret + baseLength);
+ deb->length = baseLength;
+ deb->magic = kMMapLengthMagic;
+ }
}
// TODO: Could technically implement MAP_POPULATE via PrefetchVirtualMemory
}
// TODO: Could technically implement MAP_POPULATE via PrefetchVirtualMemory
// in debug mode.
MEMORY_BASIC_INFORMATION inf;
VirtualQuery(addr, &inf, sizeof(inf));
// in debug mode.
MEMORY_BASIC_INFORMATION inf;
VirtualQuery(addr, &inf, sizeof(inf));
- assert(inf.BaseAddress == addr);
- assert(inf.RegionSize == alignToAllocationGranularity(length));
+ assert(inf.AllocationBase == addr);
+
+ auto deb = (MemMapDebugTrailer*)((char*)addr + length);
+ assert(deb->length == length);
+ assert(deb->magic == kMMapLengthMagic);
}
if (!VirtualFree(addr, 0, MEM_RELEASE)) {
return -1;
}
if (!VirtualFree(addr, 0, MEM_RELEASE)) {
return -1;