diff options
author | Chris Apple <cja-private@pm.me> | 2024-09-25 11:59:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-25 11:59:11 -0700 |
commit | c3334dad732e3a3a53e57c028bdb337766e01598 (patch) | |
tree | 8145dac97562f3c6a832dc278e33ad481babc59a | |
parent | 0f521931b85e6b5f798af357cf32a7ae782a848d (diff) | |
download | llvm-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.txt | 8 | ||||
-rw-r--r-- | compiler-rt/lib/rtsan/rtsan.cpp | 9 | ||||
-rw-r--r-- | compiler-rt/lib/rtsan/rtsan_flags.inc | 1 | ||||
-rw-r--r-- | compiler-rt/lib/rtsan/rtsan_stats.cpp | 35 | ||||
-rw-r--r-- | compiler-rt/lib/rtsan/rtsan_stats.h | 21 | ||||
-rw-r--r-- | compiler-rt/test/rtsan/exit_stats.cpp | 23 |
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 |