diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp index 9f4a9a5701636..7691815fd5c1d 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 4646e750b6796..745cbea0eb3a2 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 -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 3b279989a49cb..5e54225025fbd 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 +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 mock_on_violation; + ::testing::MockFunction + 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,