diff options
| author | Alex Shlyapnikov <alekseys@google.com> | 2018-06-20 17:10:33 +0000 |
|---|---|---|
| committer | Alex Shlyapnikov <alekseys@google.com> | 2018-06-20 17:10:33 +0000 |
| commit | 7e067ab1afec1984e8c9d663a333d145f66c2adf (patch) | |
| tree | e6eaeb781b743cd9851596dab7cfbd08cb1c4a0a /compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc | |
| parent | 8e3e374e5f72d7a89a0903b0d1c8fbd18b2b8f9d (diff) | |
| download | bcm5719-llvm-7e067ab1afec1984e8c9d663a333d145f66c2adf.tar.gz bcm5719-llvm-7e067ab1afec1984e8c9d663a333d145f66c2adf.zip | |
[Sanitizers] Remove OOM/BadRequest allocator error handling policies.
Summary:
Remove the generic error nadling policies and handle each allocator error
explicitly. Although more verbose, it allows for more comprehensive, precise
and actionable allocator related failure reports.
This finishes up the series of changes of the particular sanitizer
allocators, improves the internal allocator error reporting and removes
now unused policies.
Reviewers: vitalybuka, cryptoad
Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D48328
llvm-svn: 335147
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 |

