[compiler-rt] [rtsan] Introduce blocking-fn-name and intercepted-fn-name suppressions (PR #112108)
Chris Apple via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 13 06:57:18 PDT 2024
https://github.com/cjappl updated https://github.com/llvm/llvm-project/pull/112108
>From b5dc1aa16882facd426a50902eba50b2753b7be9 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sat, 12 Oct 2024 12:10:26 -0700
Subject: [PATCH 1/2] [rtsan] Introduce blocking-fn-name and
intercepted-fn-name suppressions
---
compiler-rt/lib/rtsan/rtsan_assertions.h | 6 +++++
compiler-rt/lib/rtsan/rtsan_checks.inc | 2 ++
compiler-rt/lib/rtsan/rtsan_suppressions.cpp | 22 +++++++++++++++++++
compiler-rt/lib/rtsan/rtsan_suppressions.h | 2 ++
compiler-rt/test/rtsan/stack_suppressions.cpp | 18 ++++++++++-----
.../test/rtsan/stack_suppressions.cpp.supp | 6 +++--
6 files changed, 49 insertions(+), 7 deletions(-)
diff --git a/compiler-rt/lib/rtsan/rtsan_assertions.h b/compiler-rt/lib/rtsan/rtsan_assertions.h
index 8183a8202478ff..2e7cb8ffc729a7 100644
--- a/compiler-rt/lib/rtsan/rtsan_assertions.h
+++ b/compiler-rt/lib/rtsan/rtsan_assertions.h
@@ -28,6 +28,12 @@ void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
if (context.InRealtimeContext() && !context.IsBypassed()) {
ScopedBypass sb{context};
+ if ((info.type == DiagnosticsInfoType::InterceptedCall &&
+ IsInterceptorSuppressed(info.func_name)) ||
+ (info.type == DiagnosticsInfoType::BlockingCall &&
+ IsBlockingFnSuppressed(info.func_name)))
+ return;
+
__sanitizer::BufferedStackTrace stack;
// We use the unwind_on_fatal flag here because of precedent with other
diff --git a/compiler-rt/lib/rtsan/rtsan_checks.inc b/compiler-rt/lib/rtsan/rtsan_checks.inc
index f5f23e044bd5d7..d9639fda7d9816 100644
--- a/compiler-rt/lib/rtsan/rtsan_checks.inc
+++ b/compiler-rt/lib/rtsan/rtsan_checks.inc
@@ -17,3 +17,5 @@
// SummaryKind should be a string literal.
RTSAN_CHECK(CallStackContains, "call-stack-contains")
+RTSAN_CHECK(InterceptedFnName, "intercepted-fn-name")
+RTSAN_CHECK(BlockingFnName, "blocking-fn-name")
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
index c5051dd1910236..a356f97517568d 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.cpp
@@ -92,3 +92,25 @@ bool __rtsan::IsStackTraceSuppressed(const StackTrace &stack) {
}
return false;
}
+
+static bool IsFunctionSuppressed(const char *interceptor_name,
+ const char *flag_name) {
+ if (suppression_ctx == nullptr)
+ return false;
+
+ if (!suppression_ctx->HasSuppressionType(flag_name))
+ return false;
+
+ Suppression *s;
+ return suppression_ctx->Match(interceptor_name, flag_name, &s);
+}
+
+bool __rtsan::IsInterceptorSuppressed(const char *interceptor_name) {
+ return IsFunctionSuppressed(
+ interceptor_name, ConvertTypeToFlagName(ErrorType::InterceptedFnName));
+}
+
+bool __rtsan::IsBlockingFnSuppressed(const char *blocking_fn_name) {
+ return IsFunctionSuppressed(blocking_fn_name,
+ ConvertTypeToFlagName(ErrorType::BlockingFnName));
+}
diff --git a/compiler-rt/lib/rtsan/rtsan_suppressions.h b/compiler-rt/lib/rtsan/rtsan_suppressions.h
index 45545f8c0e0b65..e2997c6e2e755b 100644
--- a/compiler-rt/lib/rtsan/rtsan_suppressions.h
+++ b/compiler-rt/lib/rtsan/rtsan_suppressions.h
@@ -18,5 +18,7 @@ namespace __rtsan {
void InitializeSuppressions();
bool IsStackTraceSuppressed(const __sanitizer::StackTrace &stack);
+bool IsInterceptorSuppressed(const char *interceptor_name);
+bool IsBlockingFnSuppressed(const char *blocking_fn_name);
} // namespace __rtsan
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp b/compiler-rt/test/rtsan/stack_suppressions.cpp
index 2aceedbb313b11..024b1e75fda806 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp
@@ -1,4 +1,5 @@
// RUN: %clangxx -fsanitize=realtime %s -o %t
+// RUN: %env_rtsan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPPRESSIONS
// RUN: %env_rtsan_opts=suppressions='%s.supp' not %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: ios
@@ -22,13 +23,14 @@ void VectorViolations() {
v.reserve(10);
}
-void BlockFunc() [[clang::blocking]] { usleep(1); }
+void BlockFunc() [[clang::blocking]] { /* do something blocking */
+}
void *process() [[clang::nonblocking]] {
- void *ptr = MallocViolation();
- VectorViolations();
- BlockFunc();
- free(ptr);
+ void *ptr = MallocViolation(); // Suppressed call-stack-contains
+ VectorViolations(); // Suppressed call-stack-contains with regex
+ BlockFunc(); // Suppressed blocking-fn-name
+ free(ptr); // Suppressed intercepted-fn-name
// This is the one that should abort the program
// Everything else is suppressed
@@ -51,3 +53,9 @@ int main() {
// CHECK-NOT: vector
// CHECK-NOT: free
// CHECK-NOT: BlockFunc
+
+// CHECK-NOSUPPRESSIONS: malloc
+// CHECK-NOSUPPRESSIONS: vector
+// CHECK-NOSUPPRESSIONS: free
+// CHECK-NOSUPPRESSIONS: BlockFunc
+// CHECK-NOSUPPRESSIONS: usleep
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
index bec4db259a3e0e..6640f5690776d2 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp.supp
@@ -1,4 +1,6 @@
call-stack-contains:MallocViolation
call-stack-contains:std::*vector
-call-stack-contains:free
-call-stack-contains:BlockFunc
+
+intercepted-fn-name:free
+
+blocking-fn-name:BlockFunc
>From 95b54aebfa301a03a2e2a719a28a2e7d5a547466 Mon Sep 17 00:00:00 2001
From: Chris Apple <cja-private at pm.me>
Date: Sun, 13 Oct 2024 06:56:57 -0700
Subject: [PATCH 2/2] [PR] self - add CAS loop in test so empty BlockFunc
doesn't get removed by compiler
---
compiler-rt/test/rtsan/stack_suppressions.cpp | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/test/rtsan/stack_suppressions.cpp b/compiler-rt/test/rtsan/stack_suppressions.cpp
index 024b1e75fda806..f81573b9bc5eb8 100644
--- a/compiler-rt/test/rtsan/stack_suppressions.cpp
+++ b/compiler-rt/test/rtsan/stack_suppressions.cpp
@@ -9,8 +9,11 @@
#include <stdlib.h>
#include <unistd.h>
+#include <atomic>
#include <vector>
+std::atomic<int> cas_atomic{0};
+
void *MallocViolation() { return malloc(10); }
void VectorViolations() {
@@ -23,7 +26,11 @@ void VectorViolations() {
v.reserve(10);
}
-void BlockFunc() [[clang::blocking]] { /* do something blocking */
+void BlockFunc() [[clang::blocking]] {
+ int expected = 0;
+ while (!cas_atomic.compare_exchange_weak(expected, 1)) {
+ expected = cas_atomic.load();
+ }
}
void *process() [[clang::nonblocking]] {
More information about the llvm-commits
mailing list