[compiler-rt] 3423a5e - [rtsan][NFC] Refactor where we unwind the stack (#111443)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 8 14:26:20 PDT 2024


Author: Chris Apple
Date: 2024-10-08T14:26:17-07:00
New Revision: 3423a5e3b779db8f2e8018fad477abff67b33404

URL: https://github.com/llvm/llvm-project/commit/3423a5e3b779db8f2e8018fad477abff67b33404
DIFF: https://github.com/llvm/llvm-project/commit/3423a5e3b779db8f2e8018fad477abff67b33404.diff

LOG: [rtsan][NFC] Refactor where we unwind the stack (#111443)

This change alters where we unwind the stack. We now do it in ExpectNotRealtime, and pass in the DiagnosticInfo and Stack to OnViolation.

Added: 
    

Modified: 
    compiler-rt/lib/rtsan/rtsan.cpp
    compiler-rt/lib/rtsan/rtsan_assertions.h
    compiler-rt/lib/rtsan/tests/rtsan_test_assertions.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp
index 9f4a9a5701636f..7691815fd5c1dc 100644
--- a/compiler-rt/lib/rtsan/rtsan.cpp
+++ b/compiler-rt/lib/rtsan/rtsan.cpp
@@ -46,41 +46,33 @@ static InitializationState GetInitializationState() {
       atomic_load(&rtsan_initialized, memory_order_acquire));
 }
 
-static auto OnViolationAction(DiagnosticsInfo info) {
-  return [info]() {
-    IncrementTotalErrorCount();
+static void OnViolation(const BufferedStackTrace &stack,
+                        const DiagnosticsInfo &info) {
+  IncrementTotalErrorCount();
 
-    BufferedStackTrace stack;
+  // If in the future we interop with other sanitizers, we will
+  // need to make our own stackdepot
+  StackDepotHandle handle = StackDepotPut_WithHandle(stack);
 
-    // We use the unwind_on_fatal flag here because of precedent with other
-    // sanitizers, this action is not necessarily fatal if halt_on_error=false
-    stack.Unwind(info.pc, info.bp, nullptr,
-                 common_flags()->fast_unwind_on_fatal);
+  const bool is_stack_novel = handle.use_count() == 0;
 
-    // If in the future we interop with other sanitizers, we will
-    // need to make our own stackdepot
-    StackDepotHandle handle = StackDepotPut_WithHandle(stack);
+  // Marked UNLIKELY as if user is runing with halt_on_error=false
+  // we expect a high number of duplicate stacks. We are willing
+  // To pay for the first insertion.
+  if (UNLIKELY(is_stack_novel)) {
+    IncrementUniqueErrorCount();
 
-    const bool is_stack_novel = handle.use_count() == 0;
+    PrintDiagnostics(info);
+    stack.Print();
 
-    // Marked UNLIKELY as if user is runing with halt_on_error=false
-    // we expect a high number of duplicate stacks. We are willing
-    // To pay for the first insertion.
-    if (UNLIKELY(is_stack_novel)) {
-      IncrementUniqueErrorCount();
+    handle.inc_use_count_unsafe();
+  }
 
-      PrintDiagnostics(info);
-      stack.Print();
-
-      handle.inc_use_count_unsafe();
-    }
-
-    if (flags().halt_on_error) {
-      if (flags().print_stats_on_exit)
-        PrintStatisticsSummary();
-      Die();
-    }
-  };
+  if (flags().halt_on_error) {
+    if (flags().print_stats_on_exit)
+      PrintStatisticsSummary();
+    Die();
+  }
 }
 
 extern "C" {
@@ -141,8 +133,8 @@ __rtsan_notify_intercepted_call(const char *func_name) {
   __rtsan_ensure_initialized();
   GET_CALLER_PC_BP;
   ExpectNotRealtime(GetContextForThisThread(),
-                    OnViolationAction({DiagnosticsInfoType::InterceptedCall,
-                                       func_name, pc, bp}));
+                    {DiagnosticsInfoType::InterceptedCall, func_name, pc, bp},
+                    OnViolation);
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE void
@@ -150,8 +142,8 @@ __rtsan_notify_blocking_call(const char *func_name) {
   __rtsan_ensure_initialized();
   GET_CALLER_PC_BP;
   ExpectNotRealtime(GetContextForThisThread(),
-                    OnViolationAction({DiagnosticsInfoType::BlockingCall,
-                                       func_name, pc, bp}));
+                    {DiagnosticsInfoType::BlockingCall, func_name, pc, bp},
+                    OnViolation);
 }
 
 } // extern "C"

diff  --git a/compiler-rt/lib/rtsan/rtsan_assertions.h b/compiler-rt/lib/rtsan/rtsan_assertions.h
index 4646e750b6796e..745cbea0eb3a29 100644
--- a/compiler-rt/lib/rtsan/rtsan_assertions.h
+++ b/compiler-rt/lib/rtsan/rtsan_assertions.h
@@ -14,15 +14,27 @@
 
 #include "rtsan/rtsan.h"
 #include "rtsan/rtsan_context.h"
+#include "rtsan/rtsan_diagnostics.h"
+
+#include "sanitizer_common/sanitizer_stacktrace.h"
 
 namespace __rtsan {
 
 template <typename OnViolationAction>
-void ExpectNotRealtime(Context &context, OnViolationAction &&OnViolation) {
+void ExpectNotRealtime(Context &context, const DiagnosticsInfo &info,
+                       OnViolationAction &&OnViolation) {
   CHECK(__rtsan_is_initialized());
   if (context.InRealtimeContext() && !context.IsBypassed()) {
     ScopedBypass sb{context};
-    OnViolation();
+
+    __sanitizer::BufferedStackTrace stack;
+
+    // We use the unwind_on_fatal flag here because of precedent with other
+    // sanitizers, this action is not necessarily fatal if halt_on_error=false
+    stack.Unwind(info.pc, info.bp, nullptr,
+                 __sanitizer::common_flags()->fast_unwind_on_fatal);
+
+    OnViolation(stack, info);
   }
 }
 

diff  --git a/compiler-rt/lib/rtsan/tests/rtsan_test_assertions.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_assertions.cpp
index 3b279989a49cb3..5e54225025fbd0 100644
--- a/compiler-rt/lib/rtsan/tests/rtsan_test_assertions.cpp
+++ b/compiler-rt/lib/rtsan/tests/rtsan_test_assertions.cpp
@@ -14,8 +14,11 @@
 
 #include "rtsan/rtsan_assertions.h"
 
+#include "sanitizer_common/sanitizer_stacktrace.h"
+
 #include <gmock/gmock.h>
 
+using namespace __sanitizer;
 using namespace __rtsan;
 
 class TestRtsanAssertions : public ::testing::Test {
@@ -25,9 +28,12 @@ class TestRtsanAssertions : public ::testing::Test {
 
 static void ExpectViolationAction(Context &context,
                                   bool expect_violation_callback) {
-  ::testing::MockFunction<void()> mock_on_violation;
+  ::testing::MockFunction<void(const BufferedStackTrace &stack,
+                               const DiagnosticsInfo &info)>
+      mock_on_violation;
   EXPECT_CALL(mock_on_violation, Call).Times(expect_violation_callback ? 1 : 0);
-  ExpectNotRealtime(context, mock_on_violation.AsStdFunction());
+  DiagnosticsInfo info{};
+  ExpectNotRealtime(context, info, mock_on_violation.AsStdFunction());
 }
 
 TEST_F(TestRtsanAssertions,


        


More information about the llvm-commits mailing list