[compiler-rt] r335147 - [Sanitizers] Remove OOM/BadRequest allocator error handling policies.

Alex Shlyapnikov via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 20 10:10:34 PDT 2018


Author: alekseyshl
Date: Wed Jun 20 10:10:33 2018
New Revision: 335147

URL: http://llvm.org/viewvc/llvm-project?rev=335147&view=rev
Log:
[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

Modified:
    compiler-rt/trunk/lib/asan/asan_errors.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_local_cache.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_primary64.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc

Modified: compiler-rt/trunk/lib/asan/asan_errors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_errors.cc?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_errors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_errors.cc Wed Jun 20 10:10:33 2018
@@ -182,7 +182,7 @@ void ErrorCallocOverflow::Print() {
       count, size, tid, ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -198,7 +198,7 @@ void ErrorPvallocOverflow::Print() {
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -212,7 +212,7 @@ void ErrorInvalidAllocationAlignment::Pr
       alignment, tid, ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -234,7 +234,7 @@ void ErrorInvalidAlignedAllocAlignment::
 #endif
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -250,7 +250,7 @@ void ErrorInvalidPosixMemalignAlignment:
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -266,7 +266,7 @@ void ErrorAllocationSizeTooBig::Print()
       ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -278,7 +278,7 @@ void ErrorRssLimitExceeded::Print() {
       "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb);
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 
@@ -290,7 +290,7 @@ void ErrorOutOfMemory::Print() {
       "0x%zx bytes\n", requested_size);
   Printf("%s", d.Default());
   stack->Print();
-  PrintHintAllocatorCannotReturnNull("ASAN_OPTIONS");
+  PrintHintAllocatorCannotReturnNull();
   ReportErrorSummary(scariness.GetDescription(), stack);
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc Wed Jun 20 10:10:33 2018
@@ -140,12 +140,19 @@ static void RawInternalFree(void *ptr, I
 
 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 s
   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(LowLeve
   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_
                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

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h Wed Jun 20 10:10:33 2018
@@ -34,26 +34,14 @@ extern const char *SecondaryAllocatorNam
 bool AllocatorMayReturnNull();
 void SetAllocatorMayReturnNull(bool may_return_null);
 
-// Allocator failure handling policies:
-// Implements AllocatorMayReturnNull policy, returns null when the flag is set,
-// dies otherwise.
-struct ReturnNullOrDieOnFailure {
-  static void *OnBadRequest();
-  static void *OnOOM();
-};
-// Always dies on the failure.
-struct DieOnFailure {
-  static void NORETURN *OnBadRequest();
-  static void NORETURN *OnOOM();
-};
-
-void PrintHintAllocatorCannotReturnNull(const char *options_name);
-
 // Returns true if allocator detected OOM condition. Can be used to avoid memory
-// hungry operations. Set when AllocatorReturnNullOrDieOnOOM() is called.
+// hungry operations.
 bool IsAllocatorOutOfMemory();
+// Should be called by a particular allocator when OOM is detected.
 void SetAllocatorOutOfMemory();
 
+void PrintHintAllocatorCannotReturnNull();
+
 // Allocators call these callbacks on mmap/munmap.
 struct NoOpMapUnmapCallback {
   void OnMap(uptr p, uptr size) const { }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_local_cache.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_local_cache.h?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_local_cache.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_local_cache.h Wed Jun 20 10:10:33 2018
@@ -260,8 +260,11 @@ struct SizeClassAllocator32LocalCache {
         class_id, allocator, (TransferBatch *)c->batch[first_idx_to_drain]);
     // Failure to allocate a batch while releasing memory is non recoverable.
     // TODO(alekseys): Figure out how to do it without allocating a new batch.
-    if (UNLIKELY(!b))
-      DieOnFailure::OnOOM();
+    if (UNLIKELY(!b)) {
+      Report("FATAL: Internal error: %s's allocator failed to allocate a "
+             "transfer batch.\n", SanitizerToolName);
+      Die();
+    }
     b->SetFromArray(&c->batch[first_idx_to_drain], count);
     c->count -= count;
     allocator->DeallocateBatch(&stats_, class_id, b);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_primary64.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_primary64.h?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_primary64.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_primary64.h Wed Jun 20 10:10:33 2018
@@ -118,8 +118,12 @@ class SizeClassAllocator64 {
     // Failure to allocate free array space while releasing memory is non
     // recoverable.
     if (UNLIKELY(!EnsureFreeArraySpace(region, region_beg,
-                                       new_num_freed_chunks)))
-      DieOnFailure::OnOOM();
+                                       new_num_freed_chunks))) {
+      Report("FATAL: Internal error: %s's allocator exhausted the free list "
+             "space for size class %zd (%zd bytes).\n", SanitizerToolName,
+             class_id, ClassIdToSize(class_id));
+      Die();
+    }
     for (uptr i = 0; i < n_chunks; i++)
       free_array[old_num_chunks + i] = chunks[i];
     region->num_freed_chunks = new_num_freed_chunks;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc?rev=335147&r1=335146&r2=335147&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc Wed Jun 20 10:10:33 2018
@@ -30,8 +30,7 @@ class ScopedAllocatorErrorReport {
   ~ScopedAllocatorErrorReport() {
     Printf("%s", d.Default());
     stack->Print();
-    // TODO(alekseyshl): Define SanitizerToolOptionsEnvVarName and use it there.
-    PrintHintAllocatorCannotReturnNull("");
+    PrintHintAllocatorCannotReturnNull();
     ReportErrorSummary(error_summary, stack);
   }
 




More information about the llvm-commits mailing list