diff options
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc | 57 |
1 files changed, 19 insertions, 38 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc index 0fdaef17f87..6bfd5e5eea5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc @@ -140,12 +140,19 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) { const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull; +static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) { + SetAllocatorOutOfMemory(); + Report("FATAL: %s: internal allocator is out of memory trying to allocate " + "0x%zx bytes\n", SanitizerToolName, requested_size); + Die(); +} + void *InternalAlloc(uptr size, InternalAllocatorCache *cache, uptr alignment) { if (size + sizeof(u64) < size) return nullptr; void *p = RawInternalAlloc(size + sizeof(u64), cache, alignment); if (UNLIKELY(!p)) - return DieOnFailure::OnOOM(); + ReportInternalAllocatorOutOfMemory(size + sizeof(u64)); ((u64*)p)[0] = kBlockMagic; return (char*)p + sizeof(u64); } @@ -160,13 +167,17 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) { CHECK_EQ(kBlockMagic, ((u64*)addr)[0]); void *p = RawInternalRealloc(addr, size, cache); if (UNLIKELY(!p)) - return DieOnFailure::OnOOM(); + ReportInternalAllocatorOutOfMemory(size); return (char*)p + sizeof(u64); } void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) { - if (UNLIKELY(CheckForCallocOverflow(count, size))) - return DieOnFailure::OnBadRequest(); + if (UNLIKELY(CheckForCallocOverflow(count, size))) { + Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) " + "cannot be represented in type size_t\n", SanitizerToolName, count, + size); + Die(); + } void *p = InternalAlloc(count * size, cache); if (LIKELY(p)) internal_memset(p, 0, count * size); @@ -215,6 +226,8 @@ void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) { low_level_alloc_callback = callback; } +// Allocator's OOM and other errors handling support. + static atomic_uint8_t allocator_out_of_memory = {0}; static atomic_uint8_t allocator_may_return_null = {0}; @@ -226,15 +239,6 @@ void SetAllocatorOutOfMemory() { atomic_store_relaxed(&allocator_out_of_memory, 1); } -// Prints error message and kills the program. -void NORETURN ReportAllocatorCannotReturnNull() { - Report("%s's allocator is terminating the process instead of returning 0\n", - SanitizerToolName); - Report("If you don't like this behavior set allocator_may_return_null=1\n"); - CHECK(0); - Die(); -} - bool AllocatorMayReturnNull() { return atomic_load(&allocator_may_return_null, memory_order_relaxed); } @@ -244,32 +248,9 @@ void SetAllocatorMayReturnNull(bool may_return_null) { memory_order_relaxed); } -void *ReturnNullOrDieOnFailure::OnBadRequest() { - if (AllocatorMayReturnNull()) - return nullptr; - ReportAllocatorCannotReturnNull(); -} - -void *ReturnNullOrDieOnFailure::OnOOM() { - atomic_store_relaxed(&allocator_out_of_memory, 1); - if (AllocatorMayReturnNull()) - return nullptr; - ReportAllocatorCannotReturnNull(); -} - -void NORETURN *DieOnFailure::OnBadRequest() { - ReportAllocatorCannotReturnNull(); -} - -void NORETURN *DieOnFailure::OnOOM() { - atomic_store_relaxed(&allocator_out_of_memory, 1); - ReportAllocatorCannotReturnNull(); -} - -// Prints hint message. -void PrintHintAllocatorCannotReturnNull(const char *options_name) { +void PrintHintAllocatorCannotReturnNull() { Report("HINT: if you don't care about these errors you may set " - "%s=allocator_may_return_null=1\n", options_name); + "allocator_may_return_null=1\n"); } } // namespace __sanitizer |