From ee8fa1631c6811b61d2027fde6641e3291bef1e4 Mon Sep 17 00:00:00 2001 From: Chris Apple Date: Thu, 26 Sep 2024 11:53:12 -0700 Subject: [PATCH] Broken on linux --- compiler-rt/lib/rtsan/rtsan.cpp | 49 +++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp index f9741b4fe3509..83c88a9f8fb8f 100644 --- a/compiler-rt/lib/rtsan/rtsan.cpp +++ b/compiler-rt/lib/rtsan/rtsan.cpp @@ -21,6 +21,9 @@ #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#include +#include + using namespace __rtsan; using namespace __sanitizer; @@ -46,10 +49,27 @@ static InitializationState GetInitializationState() { atomic_load(&rtsan_initialized, memory_order_acquire)); } -static auto OnViolationAction(DiagnosticsInfo info) { - return [info]() { - IncrementTotalErrorCount(); +template +constexpr static decltype(auto) BuildErrorAction(PairTypes&&... pairs) { + return [actions = std::tuple(std::forward(pairs)...)]() { + std::apply([](auto&&... action_pair) { + ((action_pair.second ? action_pair.first() : void()), ...); + }, actions); + }; +} + +template +constexpr decltype(auto) OptionallyCall(Callable&& action, bool condition) { + return std::make_pair(std::forward(action), condition); +} +template +constexpr decltype(auto) AlwaysCall(Callable&& action) { + return OptionallyCall(std::forward(action), true); + } + +void StoreStackAndPrintIfNovel(const DiagnosticsInfo& info) +{ BufferedStackTrace stack; // We use the unwind_on_fatal flag here because of precedent with other @@ -74,10 +94,6 @@ static auto OnViolationAction(DiagnosticsInfo info) { handle.inc_use_count_unsafe(); } - - if (flags().halt_on_error) - Die(); - }; } extern "C" { @@ -137,18 +153,29 @@ __rtsan_notify_intercepted_call(const char *func_name) { __rtsan_ensure_initialized(); GET_CALLER_PC_BP; + DiagnosticsInfoType type = DiagnosticsInfoType::InterceptedCall; ExpectNotRealtime(GetContextForThisThread(), - OnViolationAction({DiagnosticsInfoType::InterceptedCall, - func_name, pc, bp})); + BuildErrorAction( + AlwaysCall(IncrementTotalErrorCount), + AlwaysCall([=]() {StoreStackAndPrintIfNovel({type, func_name, pc, bp});}), + OptionallyCall(Die, flags().halt_on_error) + ) + ); } SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_notify_blocking_call(const char *func_name) { __rtsan_ensure_initialized(); GET_CALLER_PC_BP; + + DiagnosticsInfoType type = DiagnosticsInfoType::BlockingCall; ExpectNotRealtime(GetContextForThisThread(), - OnViolationAction({DiagnosticsInfoType::BlockingCall, - func_name, pc, bp})); + BuildErrorAction( + AlwaysCall(IncrementTotalErrorCount), + AlwaysCall([=]() {StoreStackAndPrintIfNovel({type, func_name, pc, bp});}), + OptionallyCall(Die, flags().halt_on_error) + ) + ); } } // extern "C"