[compiler-rt] 6318001 - [sanitizer] Support IsRssLimitExceeded in all sanitizers

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 3 12:45:54 PST 2021


Author: Vitaly Buka
Date: 2021-12-03T12:45:44-08:00
New Revision: 6318001209932f075fd6f12439ec9e0327e9af05

URL: https://github.com/llvm/llvm-project/commit/6318001209932f075fd6f12439ec9e0327e9af05
DIFF: https://github.com/llvm/llvm-project/commit/6318001209932f075fd6f12439ec9e0327e9af05.diff

LOG: [sanitizer] Support IsRssLimitExceeded in all sanitizers

Reviewed By: kstoimenov

Differential Revision: https://reviews.llvm.org/D115000

Added: 
    

Modified: 
    compiler-rt/lib/asan/asan_rtl.cpp
    compiler-rt/lib/dfsan/dfsan_allocator.cpp
    compiler-rt/lib/hwasan/hwasan_allocator.cpp
    compiler-rt/lib/lsan/lsan_allocator.cpp
    compiler-rt/lib/memprof/memprof_rtl.cpp
    compiler-rt/lib/msan/msan_allocator.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
    compiler-rt/lib/tsan/rtl/tsan_mman.cpp
    compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cpp
    compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index f13994e6270a3..9f2afd1e8f0b5 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -371,11 +371,6 @@ void PrintAddressSpaceLayout() {
           kHighShadowBeg > kMidMemEnd);
 }
 
-static bool UNUSED __local_asan_dyninit = [] {
-  MaybeStartBackgroudThread();
-  return false;
-}();
-
 static void AsanInitInternal() {
   if (LIKELY(asan_inited)) return;
   SanitizerToolName = "AddressSanitizer";

diff  --git a/compiler-rt/lib/dfsan/dfsan_allocator.cpp b/compiler-rt/lib/dfsan/dfsan_allocator.cpp
index b2e94564446e0..c50aee7a55a0f 100644
--- a/compiler-rt/lib/dfsan/dfsan_allocator.cpp
+++ b/compiler-rt/lib/dfsan/dfsan_allocator.cpp
@@ -87,6 +87,12 @@ static void *DFsanAllocate(uptr size, uptr alignment, bool zeroise) {
     BufferedStackTrace stack;
     ReportAllocationSizeTooBig(size, max_malloc_size, &stack);
   }
+  if (UNLIKELY(IsRssLimitExceeded())) {
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    BufferedStackTrace stack;
+    ReportRssLimitExceeded(&stack);
+  }
   DFsanThread *t = GetCurrentThread();
   void *allocated;
   if (t) {

diff  --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
index 9e1729964e277..84e183f2384f2 100644
--- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp
@@ -132,6 +132,11 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment,
     }
     ReportAllocationSizeTooBig(orig_size, kMaxAllowedMallocSize, stack);
   }
+  if (UNLIKELY(IsRssLimitExceeded())) {
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    ReportRssLimitExceeded(stack);
+  }
 
   alignment = Max(alignment, kShadowAlignment);
   uptr size = TaggedSize(orig_size);

diff  --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp
index 91e34ebb32143..9af7bbbb01ec0 100644
--- a/compiler-rt/lib/lsan/lsan_allocator.cpp
+++ b/compiler-rt/lib/lsan/lsan_allocator.cpp
@@ -88,6 +88,11 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
     size = 1;
   if (size > max_malloc_size)
     return ReportAllocationSizeTooBig(size, stack);
+  if (UNLIKELY(IsRssLimitExceeded())) {
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    ReportRssLimitExceeded(&stack);
+  }
   void *p = allocator.Allocate(GetAllocatorCache(), size, alignment);
   if (UNLIKELY(!p)) {
     SetAllocatorOutOfMemory();

diff  --git a/compiler-rt/lib/memprof/memprof_rtl.cpp b/compiler-rt/lib/memprof/memprof_rtl.cpp
index f947a11e0bf06..c3d1c5f096fbe 100644
--- a/compiler-rt/lib/memprof/memprof_rtl.cpp
+++ b/compiler-rt/lib/memprof/memprof_rtl.cpp
@@ -133,11 +133,6 @@ void PrintAddressSpaceLayout() {
   CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
 }
 
-static bool UNUSED __local_memprof_dyninit = [] {
-  MaybeStartBackgroudThread();
-  return false;
-}();
-
 static void MemprofInitInternal() {
   if (LIKELY(memprof_inited))
     return;

diff  --git a/compiler-rt/lib/msan/msan_allocator.cpp b/compiler-rt/lib/msan/msan_allocator.cpp
index a97bd8371e081..dc006457a59ff 100644
--- a/compiler-rt/lib/msan/msan_allocator.cpp
+++ b/compiler-rt/lib/msan/msan_allocator.cpp
@@ -160,6 +160,11 @@ static void *MsanAllocate(StackTrace *stack, uptr size, uptr alignment,
     }
     ReportAllocationSizeTooBig(size, max_malloc_size, stack);
   }
+  if (UNLIKELY(IsRssLimitExceeded())) {
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    ReportRssLimitExceeded(stack);
+  }
   MsanThread *t = GetCurrentThread();
   void *allocated;
   if (t) {

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index db03a6bc73e02..945cdf3c868dd 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -932,7 +932,6 @@ inline uptr GetPthreadDestructorIterations() {
 
 void *internal_start_thread(void *(*func)(void*), void *arg);
 void internal_join_thread(void *th);
-void MaybeStartBackgroudThread();
 
 // Make the compiler think that something is going on there.
 // Use this inside a loop that looks like memset/memcpy/etc to prevent the

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
index 6a972a29c1d04..bab77b4deff8c 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
@@ -77,11 +77,9 @@ void *BackgroundThread(void *arg) {
     }
   }
 }
-#endif
 
-void MaybeStartBackgroudThread() {
-#if (SANITIZER_LINUX || SANITIZER_NETBSD) && \
-    !SANITIZER_GO  // Need to implement/test on other platforms.
+static void MaybeStartBackgroudThread() {
+  // Need to implement/test on other platforms.
   // Start the background thread if one of the rss limits is given.
   if (!common_flags()->hard_rss_limit_mb &&
       !common_flags()->soft_rss_limit_mb &&
@@ -96,9 +94,19 @@ void MaybeStartBackgroudThread() {
     started = true;
     internal_start_thread(BackgroundThread, nullptr);
   }
-#endif
 }
 
+#  pragma clang diagnostic push
+// We avoid global-constructors to be sure that globals are ready when
+// sanitizers need them. This can happend before global constructors executed.
+// Here we don't mind if thread is started on later stages.
+#  pragma clang diagnostic ignored "-Wglobal-constructors"
+static struct BackgroudThreadStarted {
+  BackgroudThreadStarted() { MaybeStartBackgroudThread(); }
+} background_thread_strarter UNUSED;
+#  pragma clang diagnostic pop
+#endif
+
 void WriteToSyslog(const char *msg) {
   InternalScopedString msg_copy;
   msg_copy.append("%s", msg);

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp
index a31bebcb6ba9a..75044c38d5d23 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp
@@ -192,6 +192,12 @@ void *user_alloc_internal(ThreadState *thr, uptr pc, uptr sz, uptr align,
     GET_STACK_TRACE_FATAL(thr, pc);
     ReportAllocationSizeTooBig(sz, malloc_limit, &stack);
   }
+  if (UNLIKELY(IsRssLimitExceeded())) {
+    if (AllocatorMayReturnNull())
+      return nullptr;
+    GET_STACK_TRACE_FATAL(thr, pc);
+    ReportRssLimitExceeded(&stack);
+  }
   void *p = allocator()->Allocate(&thr->proc()->alloc_cache, sz, align);
   if (UNLIKELY(!p)) {
     SetAllocatorOutOfMemory();

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cpp
index f7d8b4d64016a..1b17a314f837a 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cpp
@@ -3,17 +3,14 @@
 //
 // Run with limit should fail:
 // RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=1     %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_1
-// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0 --implicit-check-not="returned null"
 
 // This run uses getrusage. We can only test getrusage when allocator_may_return_null=0
 // because getrusage gives us max-rss, not current-rss.
-// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0 --implicit-check-not="returned null"
 // REQUIRES: stable-runtime
 
-// FIXME: make it work for other sanitizers.
-// XFAIL: lsan
-// XFAIL: tsan
-// XFAIL: msan
+// Ubsan does not intercept pthread_create.
 // XFAIL: ubsan
 
 // https://github.com/google/sanitizers/issues/981
@@ -30,8 +27,8 @@ static const int kAllocSize = 1 << 20;  // Large enough to go via mmap.
 static char *allocs[kMaxNumAllocs];
 
 int main() {
-  int num_allocs = kMaxNumAllocs / 4;
-  for (int i = 0; i < 3; i++, num_allocs *= 2) {
+  int num_allocs = kMaxNumAllocs / 16;
+  for (int i = 0; num_allocs <= kMaxNumAllocs; i++, num_allocs *= 2) {
     fprintf(stderr, "[%d] allocating %d times\n", i, num_allocs);
     int zero_results = 0;
     for (int j = 0; j < num_allocs; j++) {
@@ -57,8 +54,8 @@ int main() {
   }
 }
 
-// CHECK_MAY_RETURN_1: allocating 128 times
-// CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null: 128
+// CHECK_MAY_RETURN_1: allocating 32 times
+// CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null:
 // CHECK_MAY_RETURN_1: allocating 256 times
 // CHECK_MAY_RETURN_1: Some of the malloc calls returned null:
 // CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null:
@@ -66,7 +63,6 @@ int main() {
 // CHECK_MAY_RETURN_1: Some of the malloc calls returned null:
 // CHECK_MAY_RETURN_1: Some of the malloc calls returned non-null:
 
-// CHECK_MAY_RETURN_0: allocating 128 times
-// CHECK_MAY_RETURN_0: Some of the malloc calls returned non-null: 128
-// CHECK_MAY_RETURN_0: allocating 256 times
+// CHECK_MAY_RETURN_0: allocating 32 times
+// CHECK_MAY_RETURN_0: Some of the malloc calls returned non-null:
 // CHECK_MAY_RETURN_0: {{SUMMARY: .*Sanitizer: rss-limit-exceeded}}

diff  --git a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
index e01d416cb80fd..64e80bee3a134 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
@@ -7,15 +7,11 @@
 // RUN: %env_tool_opts=hard_rss_limit_mb=100:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s
 //
 // Run w/o limit or with a large enough limit should pass:
-// RUN: %env_tool_opts=hard_rss_limit_mb=1000 %run %t
+// RUN: %env_tool_opts=hard_rss_limit_mb=4000 %run %t
 // RUN: %run %t
 //
-// FIXME: make it work for other sanitizers.
-// XFAIL: lsan
-// XFAIL: tsan
-// XFAIL: msan
+// Ubsan does not intercept pthread_create.
 // XFAIL: ubsan
-
 // UNSUPPORTED: freebsd, solaris, darwin
 
 #include <string.h>


        


More information about the llvm-commits mailing list