Skip to content

Commit c59ecbe

Browse files
committed
[rtsan] Only print out unique stack traces
1 parent c3334da commit c59ecbe

File tree

6 files changed

+65
-9
lines changed

6 files changed

+65
-9
lines changed

compiler-rt/lib/rtsan/rtsan.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "sanitizer_common/sanitizer_atomic.h"
1919
#include "sanitizer_common/sanitizer_common.h"
2020
#include "sanitizer_common/sanitizer_mutex.h"
21+
#include "sanitizer_common/sanitizer_stackdepot.h"
2122
#include "sanitizer_common/sanitizer_stacktrace.h"
2223

2324
using namespace __rtsan;
@@ -49,7 +50,21 @@ static auto OnViolationAction(DiagnosticsInfo info) {
4950
return [info]() {
5051
IncrementTotalErrorCount();
5152

52-
PrintDiagnostics(info);
53+
BufferedStackTrace stack;
54+
stack.Unwind(info.pc, info.bp, nullptr,
55+
/*request_fast*/ true);
56+
57+
StackDepotHandle handle = StackDepotPut_WithHandle(stack);
58+
59+
const bool is_stack_novel = handle.use_count() == 0;
60+
if (UNLIKELY(is_stack_novel)) {
61+
IncrementUniqueErrorCount();
62+
63+
PrintDiagnostics(info);
64+
stack.Print();
65+
66+
handle.inc_use_count_unsafe();
67+
}
5368

5469
if (flags().halt_on_error)
5570
Die();

compiler-rt/lib/rtsan/rtsan_diagnostics.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,6 @@ class Decorator : public __sanitizer::SanitizerCommonDecorator {
3939
};
4040
} // namespace
4141

42-
static void PrintStackTrace(uptr pc, uptr bp) {
43-
BufferedStackTrace stack{};
44-
45-
stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
46-
stack.Print();
47-
}
48-
4942
static void PrintError(const Decorator &decorator,
5043
const DiagnosticsInfo &info) {
5144
const auto ErrorTypeStr = [&info]() -> const char * {
@@ -91,5 +84,4 @@ void __rtsan::PrintDiagnostics(const DiagnosticsInfo &info) {
9184
PrintError(d, info);
9285
PrintReason(d, info);
9386
Printf("%s", d.Default());
94-
PrintStackTrace(info.pc, info.bp);
9587
}

compiler-rt/lib/rtsan/rtsan_stats.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,27 @@ using namespace __sanitizer;
1919
using namespace __rtsan;
2020

2121
static atomic_uint32_t rtsan_total_error_count{0};
22+
static atomic_uint32_t rtsan_unique_error_count{0};
2223

2324
void __rtsan::IncrementTotalErrorCount() {
2425
atomic_fetch_add(&rtsan_total_error_count, 1, memory_order_relaxed);
2526
}
2627

28+
void __rtsan::IncrementUniqueErrorCount() {
29+
atomic_fetch_add(&rtsan_unique_error_count, 1, memory_order_relaxed);
30+
}
31+
2732
static u32 GetTotalErrorCount() {
2833
return atomic_load(&rtsan_total_error_count, memory_order_relaxed);
2934
}
3035

36+
static u32 GetUniqueErrorCount() {
37+
return atomic_load(&rtsan_unique_error_count, memory_order_relaxed);
38+
}
39+
3140
void __rtsan::PrintStatisticsSummary() {
3241
ScopedErrorReportLock l;
3342
Printf("RealtimeSanitizer exit stats:\n");
3443
Printf(" Total error count: %u\n", GetTotalErrorCount());
44+
Printf(" Unique error count: %u\n", GetUniqueErrorCount());
3545
}

compiler-rt/lib/rtsan/rtsan_stats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
namespace __rtsan {
1616

1717
void IncrementTotalErrorCount();
18+
void IncrementUniqueErrorCount();
1819

1920
void PrintStatisticsSummary();
2021

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clangxx -fsanitize=realtime %s -o %t
2+
// RUN: env RTSAN_OPTIONS="halt_on_error=false,print_stats_on_exit=true" %run %t 2>&1 | FileCheck %s
3+
// RUN: env RTSAN_OPTIONS="halt_on_error=false" %run %t 2>&1 | grep "==ERROR: RealtimeSanitizer:" | wc -l | awk '{exit $1 != 4}'
4+
5+
// UNSUPPORTED: ios
6+
7+
// Intent: Ensure all errors are deduplicated.
8+
9+
#include <unistd.h>
10+
11+
const int kNumViolations = 10;
12+
13+
void violation() [[clang::nonblocking]] {
14+
for (int i = 0; i < kNumViolations; i++)
15+
usleep(1);
16+
}
17+
18+
void violation2() [[clang::nonblocking]] {
19+
for (int i = 0; i < kNumViolations; i++)
20+
violation();
21+
}
22+
23+
void double_violation() [[clang::nonblocking]] {
24+
violation();
25+
violation2();
26+
}
27+
28+
int main() {
29+
violation(); // 1 unique errors here, but 10 total
30+
violation2(); // 1 unique errors here, but 100 total
31+
double_violation(); // 2 unique errors here, but 110 total
32+
return 0;
33+
}
34+
35+
// CHECK: RealtimeSanitizer exit stats:
36+
// CHECK-NEXT: Total error count: 220
37+
// CHECK-NEXT: Unique error count: 4

compiler-rt/test/rtsan/exit_stats.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ int main() {
2121

2222
// CHECK: RealtimeSanitizer exit stats:
2323
// CHECK-NEXT: Total error count: 10
24+
// CHECK-NEXT: Unique error count: 1

0 commit comments

Comments
 (0)