Skip to content

Commit 64f8bca

Browse files
committed
[Runtime] Add a NULL check to MetadataAllocator.
MetadataAllocator should never return NULL, but bugs or corruption could potentially make that happen. On the large path, switch from malloc to swift_slowAlloc, which aborts on failure. On the pool path, check for a NULL allocation pointer, and log a bunch of information about the allocation request and the allocator's current state. rdar://84503396
1 parent 127874e commit 64f8bca

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5953,9 +5953,9 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
59535953
static OnceToken_t getenvToken;
59545954
SWIFT_ONCE_F(getenvToken, checkAllocatorDebugEnvironmentVariables, nullptr);
59555955

5956-
// If the size is larger than the maximum, just use malloc.
5956+
// If the size is larger than the maximum, just do a normal heap allocation.
59575957
if (size > PoolRange::MaxPoolAllocationSize) {
5958-
void *allocation = malloc(size);
5958+
void *allocation = swift_slowAlloc(size, alignment - 1);
59595959
memsetScribble(allocation, size);
59605960
return allocation;
59615961
}
@@ -5995,6 +5995,21 @@ void *MetadataAllocator::Allocate(size_t size, size_t alignment) {
59955995
__asan_poison_memory_region(allocation, newState.Remaining);
59965996
}
59975997

5998+
// NULL should be impossible, but check anyway in case of bugs or corruption
5999+
if (SWIFT_UNLIKELY(!allocation)) {
6000+
PoolRange curStateReRead = AllocationPool.load(std::memory_order_relaxed);
6001+
swift::fatalError(
6002+
0,
6003+
"Metadata allocator corruption: allocation is NULL. "
6004+
"curState: {%p, %zu} - curStateReRead: {%p, %zu} - "
6005+
"newState: {%p, %zu} - allocatedNewPage: %s - requested size: %zu - "
6006+
"sizeWithHeader: %zu - alignment: %zu - Tag: %d\n",
6007+
curState.Begin, curState.Remaining, curStateReRead.Begin,
6008+
curStateReRead.Remaining, newState.Begin, newState.Remaining,
6009+
allocatedNewPage ? "true" : "false", size, sizeWithHeader, alignment,
6010+
Tag);
6011+
}
6012+
59986013
// Swap in the new state.
59996014
if (std::atomic_compare_exchange_weak_explicit(&AllocationPool,
60006015
&curState, newState,
@@ -6035,7 +6050,7 @@ void MetadataAllocator::Deallocate(const void *allocation, size_t size,
60356050
__asan_poison_memory_region(allocation, size);
60366051

60376052
if (size > PoolRange::MaxPoolAllocationSize) {
6038-
free(const_cast<void*>(allocation));
6053+
swift_slowDealloc(const_cast<void *>(allocation), size, Alignment - 1);
60396054
return;
60406055
}
60416056

0 commit comments

Comments
 (0)