Skip to content

Commit 1efa662

Browse files
authored
[rtsan] Introduce function-name-matches suppression (#112108)
Introduces a new type of suppression: 1. function-name-matches - allows users to disable `malloc`, `free`, `pthread_mutex_lock` or similar. This could be helpful if a user thinks these are real-time safe on their OS. Also allows disabling of any function marked [[blocking]]. This is useful as a **more performant "early outs" compared to the `call-stack-contains` suppression**. `call-stack-contains` is inherently VERY costly, needing to inspect every frame of every stack for a matching string. This new suppression has an early out before we unwind the stack.
1 parent afc6da4 commit 1efa662

File tree

6 files changed

+41
-7
lines changed

6 files changed

+41
-7
lines changed

compiler-rt/lib/rtsan/rtsan_assertions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
2828
if (context.InRealtimeContext() && !context.IsBypassed()) {
2929
ScopedBypass sb{context};
3030

31+
if (IsFunctionSuppressed(info.func_name))
32+
return;
33+
3134
__sanitizer::BufferedStackTrace stack;
3235

3336
// We use the unwind_on_fatal flag here because of precedent with other

compiler-rt/lib/rtsan/rtsan_checks.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
// SummaryKind should be a string literal.
1818

1919
RTSAN_CHECK(CallStackContains, "call-stack-contains")
20+
RTSAN_CHECK(FunctionNameMatches, "function-name-matches")

compiler-rt/lib/rtsan/rtsan_suppressions.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,16 @@ bool __rtsan::IsStackTraceSuppressed(const StackTrace &stack) {
9292
}
9393
return false;
9494
}
95+
96+
bool __rtsan::IsFunctionSuppressed(const char *function_name) {
97+
if (suppression_ctx == nullptr)
98+
return false;
99+
100+
const char *flag_name = ConvertTypeToFlagName(ErrorType::FunctionNameMatches);
101+
102+
if (!suppression_ctx->HasSuppressionType(flag_name))
103+
return false;
104+
105+
Suppression *s;
106+
return suppression_ctx->Match(function_name, flag_name, &s);
107+
}

compiler-rt/lib/rtsan/rtsan_suppressions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ namespace __rtsan {
1818

1919
void InitializeSuppressions();
2020
bool IsStackTraceSuppressed(const __sanitizer::StackTrace &stack);
21+
bool IsFunctionSuppressed(const char *function_name);
2122

2223
} // namespace __rtsan

compiler-rt/test/rtsan/stack_suppressions.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clangxx -fsanitize=realtime %s -o %t
2+
// RUN: %env_rtsan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOSUPPRESSIONS
23
// RUN: %env_rtsan_opts=suppressions='%s.supp' not %run %t 2>&1 | FileCheck %s
34
// UNSUPPORTED: ios
45

@@ -8,8 +9,11 @@
89
#include <stdlib.h>
910
#include <unistd.h>
1011

12+
#include <atomic>
1113
#include <vector>
1214

15+
std::atomic<int> cas_atomic{0};
16+
1317
void *MallocViolation() { return malloc(10); }
1418

1519
void VectorViolations() {
@@ -22,13 +26,18 @@ void VectorViolations() {
2226
v.reserve(10);
2327
}
2428

25-
void BlockFunc() [[clang::blocking]] { usleep(1); }
29+
void BlockFunc() [[clang::blocking]] {
30+
int expected = 0;
31+
while (!cas_atomic.compare_exchange_weak(expected, 1)) {
32+
expected = cas_atomic.load();
33+
}
34+
}
2635

2736
void *process() [[clang::nonblocking]] {
28-
void *ptr = MallocViolation();
29-
VectorViolations();
30-
BlockFunc();
31-
free(ptr);
37+
void *ptr = MallocViolation(); // Suppressed call-stack-contains
38+
VectorViolations(); // Suppressed call-stack-contains with regex
39+
BlockFunc(); // Suppressed function-name-matches
40+
free(ptr); // Suppressed function-name-matches
3241

3342
// This is the one that should abort the program
3443
// Everything else is suppressed
@@ -51,3 +60,9 @@ int main() {
5160
// CHECK-NOT: vector
5261
// CHECK-NOT: free
5362
// CHECK-NOT: BlockFunc
63+
64+
// CHECK-NOSUPPRESSIONS: malloc
65+
// CHECK-NOSUPPRESSIONS: vector
66+
// CHECK-NOSUPPRESSIONS: free
67+
// CHECK-NOSUPPRESSIONS: BlockFunc
68+
// CHECK-NOSUPPRESSIONS: usleep
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
call-stack-contains:MallocViolation
22
call-stack-contains:std::*vector
3-
call-stack-contains:free
4-
call-stack-contains:BlockFunc
3+
4+
function-name-matches:free
5+
function-name-matches:Block*

0 commit comments

Comments
 (0)