From 91bf355bb7931df2c61902d36f55d266b219c96a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 9 Dec 2022 16:58:15 +0100 Subject: [PATCH] dnsdist: Add TSAN annotations in the channel code So Thread Sanitizer knows that the object we are passing is no longer used in the sender, and will now be used in the receiver (happens-before). --- pdns/channel.hh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pdns/channel.hh b/pdns/channel.hh index fd82ca1970..b13b3f9881 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -25,6 +25,20 @@ #include "misc.hh" +/* g++ defines __SANITIZE_THREAD__ + clang++ supports the nice __has_feature(thread_sanitizer), + let's merge them */ +#if defined(__has_feature) +#if __has_feature(thread_sanitizer) +#define __SANITIZE_THREAD__ 1 +#endif +#endif + +#if __SANITIZE_THREAD__ +extern "C" void __tsan_acquire(void *addr); +extern "C" void __tsan_release(void *addr); +#endif + namespace pdns { namespace channel @@ -210,6 +224,9 @@ namespace channel auto ptr = object.get(); static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); while (true) { +#if __SANITIZE_THREAD__ + __tsan_release(ptr); +#endif /* __SANITIZE_THREAD__ */ ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); if (sent == sizeof(ptr)) { @@ -218,6 +235,9 @@ namespace channel return true; } else { +#if __SANITIZE_THREAD__ + __tsan_acquire(ptr); +#endif /* __SANITIZE_THREAD__ */ if (errno == EINTR) { continue; } @@ -251,6 +271,9 @@ namespace channel T* obj{nullptr}; ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); if (got == sizeof(obj)) { +#if __SANITIZE_THREAD__ + __tsan_acquire(obj); +#endif /* __SANITIZE_THREAD__ */ return std::unique_ptr(obj, deleter); } else if (got == 0) { -- 2.47.2