aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Apple <cja-private@pm.me>2024-09-25 11:59:11 -0700
committerGitHub <noreply@github.com>2024-09-25 11:59:11 -0700
commitc3334dad732e3a3a53e57c028bdb337766e01598 (patch)
tree8145dac97562f3c6a832dc278e33ad481babc59a
parent0f521931b85e6b5f798af357cf32a7ae782a848d (diff)
downloadllvm-c3334dad732e3a3a53e57c028bdb337766e01598.zip
llvm-c3334dad732e3a3a53e57c028bdb337766e01598.tar.gz
llvm-c3334dad732e3a3a53e57c028bdb337766e01598.tar.bz2
[rtsan] Add exit statistics (#109885)
adds the flag `print_stats_on_exit` which mirrors nsan's same flag. # Why? Not only is this nice for the end users, this gives us a very trivial way to test deduplication which is next up Currently the style is something like: ``` RealtimeSanitizer exit stats: Total error count: 488 ```
-rw-r--r--compiler-rt/lib/rtsan/CMakeLists.txt8
-rw-r--r--compiler-rt/lib/rtsan/rtsan.cpp9
-rw-r--r--compiler-rt/lib/rtsan/rtsan_flags.inc1
-rw-r--r--compiler-rt/lib/rtsan/rtsan_stats.cpp35
-rw-r--r--compiler-rt/lib/rtsan/rtsan_stats.h21
-rw-r--r--compiler-rt/test/rtsan/exit_stats.cpp23
6 files changed, 94 insertions, 3 deletions
diff --git a/compiler-rt/lib/rtsan/CMakeLists.txt b/compiler-rt/lib/rtsan/CMakeLists.txt
index b7e2362d..af34fb6 100644
--- a/compiler-rt/lib/rtsan/CMakeLists.txt
+++ b/compiler-rt/lib/rtsan/CMakeLists.txt
@@ -5,7 +5,9 @@ set(RTSAN_CXX_SOURCES
rtsan_context.cpp
rtsan_diagnostics.cpp
rtsan_flags.cpp
- rtsan_interceptors.cpp)
+ rtsan_interceptors.cpp
+ rtsan_stats.cpp
+ )
set(RTSAN_PREINIT_SOURCES
rtsan_preinit.cpp)
@@ -16,7 +18,9 @@ set(RTSAN_HEADERS
rtsan_context.h
rtsan_diagnostics.h
rtsan_flags.h
- rtsan_flags.inc)
+ rtsan_flags.inc
+ rtsan_stats.h
+ )
set(RTSAN_DEPS)
diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index f02e894..87c3611 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -13,6 +13,7 @@
#include "rtsan/rtsan_diagnostics.h"
#include "rtsan/rtsan_flags.h"
#include "rtsan/rtsan_interceptors.h"
+#include "rtsan/rtsan_stats.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
@@ -46,7 +47,10 @@ static InitializationState GetInitializationState() {
static auto OnViolationAction(DiagnosticsInfo info) {
return [info]() {
- __rtsan::PrintDiagnostics(info);
+ IncrementTotalErrorCount();
+
+ PrintDiagnostics(info);
+
if (flags().halt_on_error)
Die();
};
@@ -62,6 +66,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
InitializeFlags();
InitializeInterceptors();
+ if (flags().print_stats_on_exit)
+ Atexit(PrintStatisticsSummary);
+
SetInitializationState(InitializationState::Initialized);
}
diff --git a/compiler-rt/lib/rtsan/rtsan_flags.inc b/compiler-rt/lib/rtsan/rtsan_flags.inc
index 25d62cf..1df71127 100644
--- a/compiler-rt/lib/rtsan/rtsan_flags.inc
+++ b/compiler-rt/lib/rtsan/rtsan_flags.inc
@@ -17,3 +17,4 @@
// See COMMON_FLAG in sanitizer_flags.inc for more details.
RTSAN_FLAG(bool, halt_on_error, true, "Exit after first reported error.")
+RTSAN_FLAG(bool, print_stats_on_exit, false, "Print stats on exit.")
diff --git a/compiler-rt/lib/rtsan/rtsan_stats.cpp b/compiler-rt/lib/rtsan/rtsan_stats.cpp
new file mode 100644
index 0000000..7c1ccf2
--- /dev/null
+++ b/compiler-rt/lib/rtsan/rtsan_stats.cpp
@@ -0,0 +1,35 @@
+//===--- rtsan_stats.cpp - Realtime Sanitizer -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Part of the RealtimeSanitizer runtime library
+//
+//===----------------------------------------------------------------------===//
+
+#include "rtsan/rtsan_stats.h"
+
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+using namespace __sanitizer;
+using namespace __rtsan;
+
+static atomic_uint32_t rtsan_total_error_count{0};
+
+void __rtsan::IncrementTotalErrorCount() {
+ atomic_fetch_add(&rtsan_total_error_count, 1, memory_order_relaxed);
+}
+
+static u32 GetTotalErrorCount() {
+ return atomic_load(&rtsan_total_error_count, memory_order_relaxed);
+}
+
+void __rtsan::PrintStatisticsSummary() {
+ ScopedErrorReportLock l;
+ Printf("RealtimeSanitizer exit stats:\n");
+ Printf(" Total error count: %u\n", GetTotalErrorCount());
+}
diff --git a/compiler-rt/lib/rtsan/rtsan_stats.h b/compiler-rt/lib/rtsan/rtsan_stats.h
new file mode 100644
index 0000000..3aa30f6
--- /dev/null
+++ b/compiler-rt/lib/rtsan/rtsan_stats.h
@@ -0,0 +1,21 @@
+//===--- rtsan_stats.h - Realtime Sanitizer ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Part of the RealtimeSanitizer runtime library
+//
+//===----------------------------------------------------------------------===//
+
+#pragma once
+
+namespace __rtsan {
+
+void IncrementTotalErrorCount();
+
+void PrintStatisticsSummary();
+
+} // namespace __rtsan
diff --git a/compiler-rt/test/rtsan/exit_stats.cpp b/compiler-rt/test/rtsan/exit_stats.cpp
new file mode 100644
index 0000000..b46a0fd
--- /dev/null
+++ b/compiler-rt/test/rtsan/exit_stats.cpp
@@ -0,0 +1,23 @@
+// RUN: %clangxx -fsanitize=realtime %s -o %t
+// RUN: env RTSAN_OPTIONS="halt_on_error=false,print_stats_on_exit=true" %run %t 2>&1 | FileCheck %s
+
+// UNSUPPORTED: ios
+
+// Intent: Ensure exits stats are printed on exit.
+
+#include <unistd.h>
+
+void violation() [[clang::nonblocking]] {
+ const int kNumViolations = 10;
+ for (int i = 0; i < kNumViolations; i++) {
+ usleep(1);
+ }
+}
+
+int main() {
+ violation();
+ return 0;
+}
+
+// CHECK: RealtimeSanitizer exit stats:
+// CHECK-NEXT: Total error count: 10