2121#include " sanitizer_common/sanitizer_stackdepot.h"
2222#include " sanitizer_common/sanitizer_stacktrace.h"
2323
24+ #include < tuple>
25+ #include < utility>
26+
2427using namespace __rtsan ;
2528using namespace __sanitizer ;
2629
@@ -46,10 +49,27 @@ static InitializationState GetInitializationState() {
4649 atomic_load (&rtsan_initialized, memory_order_acquire));
4750}
4851
49- static auto OnViolationAction (DiagnosticsInfo info) {
50- return [info]() {
51- IncrementTotalErrorCount ();
52+ template <class ...PairTypes>
53+ constexpr static decltype (auto ) BuildErrorAction(PairTypes&&... pairs) {
54+ return [actions = std::tuple (std::forward<PairTypes>(pairs)...)]() {
55+ std::apply ([](auto &&... action_pair) {
56+ ((action_pair.second ? action_pair.first () : void ()), ...);
57+ }, actions);
58+ };
59+ }
60+
61+ template <typename Callable>
62+ constexpr decltype (auto ) OptionallyCall(Callable&& action, bool condition) {
63+ return std::make_pair (std::forward<Callable>(action), condition);
64+ }
5265
66+ template <typename Callable>
67+ constexpr decltype (auto ) AlwaysCall(Callable&& action) {
68+ return OptionallyCall (std::forward<Callable>(action), true );
69+ }
70+
71+ void StoreStackAndPrintIfNovel (const DiagnosticsInfo& info)
72+ {
5373 BufferedStackTrace stack;
5474
5575 // We use the unwind_on_fatal flag here because of precedent with other
@@ -74,10 +94,6 @@ static auto OnViolationAction(DiagnosticsInfo info) {
7494
7595 handle.inc_use_count_unsafe ();
7696 }
77-
78- if (flags ().halt_on_error )
79- Die ();
80- };
8197}
8298
8399extern " C" {
@@ -137,18 +153,29 @@ __rtsan_notify_intercepted_call(const char *func_name) {
137153
138154 __rtsan_ensure_initialized ();
139155 GET_CALLER_PC_BP;
156+ DiagnosticsInfoType type = DiagnosticsInfoType::InterceptedCall;
140157 ExpectNotRealtime (GetContextForThisThread (),
141- OnViolationAction ({DiagnosticsInfoType::InterceptedCall,
142- func_name, pc, bp}));
158+ BuildErrorAction (
159+ AlwaysCall (IncrementTotalErrorCount),
160+ AlwaysCall ([=]() {StoreStackAndPrintIfNovel ({type, func_name, pc, bp});}),
161+ OptionallyCall (Die, flags ().halt_on_error )
162+ )
163+ );
143164}
144165
145166SANITIZER_INTERFACE_ATTRIBUTE void
146167__rtsan_notify_blocking_call (const char *func_name) {
147168 __rtsan_ensure_initialized ();
148169 GET_CALLER_PC_BP;
170+
171+ DiagnosticsInfoType type = DiagnosticsInfoType::BlockingCall;
149172 ExpectNotRealtime (GetContextForThisThread (),
150- OnViolationAction ({DiagnosticsInfoType::BlockingCall,
151- func_name, pc, bp}));
173+ BuildErrorAction (
174+ AlwaysCall (IncrementTotalErrorCount),
175+ AlwaysCall ([=]() {StoreStackAndPrintIfNovel ({type, func_name, pc, bp});}),
176+ OptionallyCall (Die, flags ().halt_on_error )
177+ )
178+ );
152179}
153180
154181} // extern "C"
0 commit comments