[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