Skip to content

[rtsan] Add exit statistics #109885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 25, 2024
Merged

[rtsan] Add exit statistics #109885

merged 3 commits into from
Sep 25, 2024

Conversation

cjappl
Copy link
Contributor

@cjappl cjappl commented Sep 25, 2024

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

What to pay attention to

As with any user printed string, I want to make sure we get it right in case people start relying on it.

Currently the style is something like:

RealtimeSanitizer exit stats:
    Total error count: 488

After deduplication it will be:

RealtimeSanitizer exit stats:
    Total error count: 488
    Unique error count: 12

I am open to any feedback on the UI/UX of this

@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Chris Apple (cjappl)

Changes

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

What to pay attention to

As with any user printed string, I want to make sure we get it right in case people start relying on it.

Currently the style is something like:

RealtimeSanitizer exit stats:
    Total error count: 488

After deduplication it will be:

RealtimeSanitizer exit stats:
    Total error count: 488
    Unique error count: 12

I am open to any feedback on the UI/UX of this


Full diff: https://github.com/llvm/llvm-project/pull/109885.diff

6 Files Affected:

  • (modified) compiler-rt/lib/rtsan/CMakeLists.txt (+6-2)
  • (modified) compiler-rt/lib/rtsan/rtsan.cpp (+11-1)
  • (modified) compiler-rt/lib/rtsan/rtsan_flags.inc (+1)
  • (added) compiler-rt/lib/rtsan/rtsan_stats.cpp (+35)
  • (added) compiler-rt/lib/rtsan/rtsan_stats.h (+21)
  • (added) compiler-rt/test/rtsan/exit_stats.cpp (+23)
diff --git a/compiler-rt/lib/rtsan/CMakeLists.txt b/compiler-rt/lib/rtsan/CMakeLists.txt
index 0fc3a3f8f48960..dec40858dbfa4c 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 1e10069f51dd3b..d31dadd8b8508b 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"
@@ -44,9 +45,15 @@ static InitializationState GetInitializationState() {
       atomic_load(&rtsan_initialized, memory_order_acquire));
 }
 
+static void RtsanAtexit() { PrintStatisticsSummary(); }
+
 static auto OnViolationAction(DiagnosticsInfo info) {
   return [info]() {
-    __rtsan::PrintDiagnostics(info);
+    if (flags().print_stats_on_exit)
+      IncrementTotalErrorCount();
+
+    PrintDiagnostics(info);
+
     if (flags().halt_on_error)
       Die();
   };
@@ -62,6 +69,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() {
   InitializeFlags();
   InitializeInterceptors();
 
+  if (flags().print_stats_on_exit)
+    Atexit(RtsanAtexit);
+
   SetInitializationState(InitializationState::Initialized);
 }
 
diff --git a/compiler-rt/lib/rtsan/rtsan_flags.inc b/compiler-rt/lib/rtsan/rtsan_flags.inc
index 25d62cf0a60fb0..1df71127d19d37 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 00000000000000..7c1ccf2876f081
--- /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 00000000000000..3aa30f6a5db76a
--- /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 00000000000000..b46a0fd62bac1a
--- /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

@cjappl
Copy link
Contributor Author

cjappl commented Sep 25, 2024

CC for review @davidtrevelyan

Copy link
Contributor

@davidtrevelyan davidtrevelyan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No comments from me other than what's already been flagged - looks good!

@cjappl cjappl merged commit c3334da into llvm:main Sep 25, 2024
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants