pdns icon indicating copy to clipboard operation
pdns copied to clipboard

Possible datarace in common_startup

Open darnuria opened this issue 2 years ago • 5 comments

  • Program: found with authoritative and reg test sqlite3 backend
  • Issue type: Bug report - data-race

Short description

Found a possible data-race with --enable-tsan

Environment

  • Operating system: Manjaro up to date
  • Software version: gcc12
  • Software source: compiling on master and 4.6.2

Steps to reproduce

  • configure pdns with: ./configure --with-dynmodules= --with-modules="gsqlite3" --enable-malloc-trace --enable-ubsan CXXFLAGS='-ggdb -DHAVE_CXX11' CFLAGS='-DHAVE_CXX11' YAHTTP_CFLAGS='-DHAVE_CXX11' --enable-coverage --enable-tsan --enable-unit-tests
  • run /start-test-stop 5300 gsqlite3 -DHAVE_CXX11 may be not needed ;)

Where

  • declarations :
    • https://github.com/PowerDNS/pdns/blob/master/pdns/common_startup.hh#L47
    • https://github.com/PowerDNS/pdns/blob/master/pdns/common_startup.cc#L63

Shared access:

  • https://github.com/PowerDNS/pdns/blob/master/pdns/common_startup.cc#L457
  • https://github.com/PowerDNS/pdns/blob/master/pdns/common_startup.cc#L459

Expected behavior

Should not have a data-race?

Actual behavior

Get a possible data-race

Naive solution

If it's enough I can make the patch (maybe). But i am not fluent in cpp, I program mainly in rust and C.

(I added all the variable as atomic may not be the desired behavior just for suggesting something, using atomics just on the right one is the way to go)

diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc
index 34a41320e..f4cdf0688 100644
--- a/pdns/common_startup.cc
+++ b/pdns/common_startup.cc
@@ -19,6 +19,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#include <atomic>
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -60,7 +61,8 @@ std::unique_ptr<DNSProxy> DP{nullptr};
 std::unique_ptr<DynListener> dl{nullptr};
 CommunicatorClass Communicator;
 shared_ptr<UDPNameserver> N;
-double avg_latency{0.0}, receive_latency{0.0}, cache_latency{0.0}, backend_latency{0.0}, send_latency{0.0};
+std::atomic<double> avg_latency{0.0}, receive_latency{0.0}, cache_latency{0.0}, backend_latency{0.0}, send_latency{0.0};
+//double avg_latency{0.0}, receive_latency{0.0}, cache_latency{0.0}, backend_latency{0.0}, send_latency{0.0};
 unique_ptr<TCPNameserver> TN;
 static vector<DNSDistributor*> g_distributors;
 vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
diff --git a/pdns/common_startup.hh b/pdns/common_startup.hh
index 849bf2435..fa982c1b0 100644
--- a/pdns/common_startup.hh
+++ b/pdns/common_startup.hh
@@ -44,7 +44,7 @@ extern std::unique_ptr<DynListener> dl;
 extern CommunicatorClass Communicator;
 extern std::shared_ptr<UDPNameserver> N;
 extern vector<std::shared_ptr<UDPNameserver> > g_udpReceivers;
-extern double avg_latency;
+extern std::atomic<double> avg_latency;
 extern std::unique_ptr<TCPNameserver> TN;
 extern void declareArguments();
 extern void declareStats();

Other information

Data race on send_latency

WARNING: ThreadSanitizer: data race (pid=1419536)
  Read of size 8 at 0x5599144cb960 by thread T7:
    #0 sendout $HOME/gandi/pdns/pdns/common_startup.cc:457 (pdns_server+0x1f4845d)
    #1 void std::__invoke_impl<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(std::__invoke_other, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f80d15)
    #2 std::enable_if<is_invocable_r_v<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>, void>::type std::__invoke_r<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f78e49)
    #3 std::_Function_handler<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), void (*)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::_M_invoke(std::_Any_data const&, std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f6dce2)
    #4 std::function<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::operator()(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int) const <null> (pdns_server+0x1f7fdd7)
    #5 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::distribute(int) <null> (pdns_server+0x1f761cc)
    #6 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}::operator()() const <null> (pdns_server+0x1f6b7bd)
    #7 void std::__invoke_impl<void, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(std::__invoke_other, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9dc31)
    #8 std::__invoke_result<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>::type std::__invoke<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9c122)
    #9 void std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (pdns_server+0x1f9a454)
    #10 std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::operator()() <null> (pdns_server+0x1f93cba)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f904e1)
    #12 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Previous write of size 8 at 0x5599144cb960 by thread T6:
    #0 sendout $HOME/gandi/pdns/pdns/common_startup.cc:457 (pdns_server+0x1f4859c)
    #1 void std::__invoke_impl<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(std::__invoke_other, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f80d15)
    #2 std::enable_if<is_invocable_r_v<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>, void>::type std::__invoke_r<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f78e49)
    #3 std::_Function_handler<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), void (*)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::_M_invoke(std::_Any_data const&, std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f6dce2)
    #4 std::function<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::operator()(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int) const <null> (pdns_server+0x1f7fdd7)
    #5 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::distribute(int) <null> (pdns_server+0x1f761cc)
    #6 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}::operator()() const <null> (pdns_server+0x1f6b7bd)
    #7 void std::__invoke_impl<void, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(std::__invoke_other, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9dc31)
    #8 std::__invoke_result<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>::type std::__invoke<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9c122)
    #9 void std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (pdns_server+0x1f9a454)
    #10 std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::operator()() <null> (pdns_server+0x1f93cba)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f904e1)
    #12 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Location is global 'send_latency' of size 8 at 0x5599144cb960 (pdns_server+0x473f960)

  Thread T7 (tid=1419546, running) created by thread T4 at:
    #0 pthread_create /usr/src/debug/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x670c9)
    #1 __gthread_create /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xd6269)
    #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:147 (libstdc++.so.6+0xd6269)
    #3 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int) <null> (pdns_server+0x1f6c9b8)
    #4 Distributor<DNSPacket, DNSPacket, PacketHandler>::Create(int) <null> (pdns_server+0x1f632ea)
    #5 qthread $HOME/gandi/pdns/pdns/common_startup.cc:472 (pdns_server+0x1f48c93)
    #6 void std::__invoke_impl<void, void (*)(unsigned int), unsigned int>(std::__invoke_other, void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9df26)
    #7 std::__invoke_result<void (*)(unsigned int), unsigned int>::type std::__invoke<void (*)(unsigned int), unsigned int>(void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9c4d5)
    #8 void std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) <null> (pdns_server+0x1f9a696)
    #9 std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::operator()() <null> (pdns_server+0x1f93d5e)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f905e3)
    #11 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Thread T6 (tid=1419545, running) created by thread T4 at:
    #0 pthread_create /usr/src/debug/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x670c9)
    #1 __gthread_create /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xd6269)
    #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:147 (libstdc++.so.6+0xd6269)
    #3 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int) <null> (pdns_server+0x1f6c9b8)
    #4 Distributor<DNSPacket, DNSPacket, PacketHandler>::Create(int) <null> (pdns_server+0x1f632ea)
    #5 qthread $HOME/gandi/pdns/pdns/common_startup.cc:472 (pdns_server+0x1f48c93)
    #6 void std::__invoke_impl<void, void (*)(unsigned int), unsigned int>(std::__invoke_other, void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9df26)
    #7 std::__invoke_result<void (*)(unsigned int), unsigned int>::type std::__invoke<void (*)(unsigned int), unsigned int>(void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9c4d5)
    #8 void std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) <null> (pdns_server+0x1f9a696)
    #9 std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::operator()() <null> (pdns_server+0x1f93d5e)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f905e3)
    #11 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

SUMMARY: ThreadSanitizer: data race $HOME/gandi/pdns/pdns/common_startup.cc:457 in sendout
==================

Datarace on avg_latency

==================
WARNING: ThreadSanitizer: data race (pid=1419536)
  Read of size 8 at 0x5599144cb940 by thread T7:
    #0 sendout $HOME/gandi/pdns/pdns/common_startup.cc:459 (pdns_server+0x1f485b8)
    #1 void std::__invoke_impl<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(std::__invoke_other, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f80d15)
    #2 std::enable_if<is_invocable_r_v<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>, void>::type std::__invoke_r<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f78e49)
    #3 std::_Function_handler<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), void (*)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::_M_invoke(std::_Any_data const&, std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f6dce2)
    #4 std::function<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::operator()(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int) const <null> (pdns_server+0x1f7fdd7)
    #5 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::distribute(int) <null> (pdns_server+0x1f761cc)
    #6 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}::operator()() const <null> (pdns_server+0x1f6b7bd)
    #7 void std::__invoke_impl<void, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(std::__invoke_other, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9dc31)
    #8 std::__invoke_result<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>::type std::__invoke<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9c122)
    #9 void std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (pdns_server+0x1f9a454)
    #10 std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::operator()() <null> (pdns_server+0x1f93cba)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f904e1)
    #12 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Previous write of size 8 at 0x5599144cb940 by thread T6:
    #0 sendout $HOME/gandi/pdns/pdns/common_startup.cc:459 (pdns_server+0x1f48681)
    #1 void std::__invoke_impl<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(std::__invoke_other, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f80d15)
    #2 std::enable_if<is_invocable_r_v<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>, void>::type std::__invoke_r<void, void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int>(void (*&)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f78e49)
    #3 std::_Function_handler<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int), void (*)(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::_M_invoke(std::_Any_data const&, std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int&&) <null> (pdns_server+0x1f6dce2)
    #4 std::function<void (std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int)>::operator()(std::unique_ptr<DNSPacket, std::default_delete<DNSPacket> >&, int) const <null> (pdns_server+0x1f7fdd7)
    #5 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::distribute(int) <null> (pdns_server+0x1f761cc)
    #6 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}::operator()() const <null> (pdns_server+0x1f6b7bd)
    #7 void std::__invoke_impl<void, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(std::__invoke_other, MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9dc31)
    #8 std::__invoke_result<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>::type std::__invoke<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}>(MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}&&) <null> (pdns_server+0x1f9c122)
    #9 void std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (pdns_server+0x1f9a454)
    #10 std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> >::operator()() <null> (pdns_server+0x1f93cba)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int)::{lambda()#1}> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f904e1)
    #12 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Location is global 'avg_latency' of size 8 at 0x5599144cb940 (pdns_server+0x473f940)

  Thread T7 (tid=1419546, running) created by thread T4 at:
    #0 pthread_create /usr/src/debug/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x670c9)
    #1 __gthread_create /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xd6269)
    #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:147 (libstdc++.so.6+0xd6269)
    #3 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int) <null> (pdns_server+0x1f6c9b8)
    #4 Distributor<DNSPacket, DNSPacket, PacketHandler>::Create(int) <null> (pdns_server+0x1f632ea)
    #5 qthread $HOME/gandi/pdns/pdns/common_startup.cc:472 (pdns_server+0x1f48c93)
    #6 void std::__invoke_impl<void, void (*)(unsigned int), unsigned int>(std::__invoke_other, void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9df26)
    #7 std::__invoke_result<void (*)(unsigned int), unsigned int>::type std::__invoke<void (*)(unsigned int), unsigned int>(void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9c4d5)
    #8 void std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) <null> (pdns_server+0x1f9a696)
    #9 std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::operator()() <null> (pdns_server+0x1f93d5e)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f905e3)
    #11 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

  Thread T6 (tid=1419545, running) created by thread T4 at:
    #0 pthread_create /usr/src/debug/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x670c9)
    #1 __gthread_create /usr/src/debug/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xd6269)
    #2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:147 (libstdc++.so.6+0xd6269)
    #3 MultiThreadDistributor<DNSPacket, DNSPacket, PacketHandler>::MultiThreadDistributor(int) <null> (pdns_server+0x1f6c9b8)
    #4 Distributor<DNSPacket, DNSPacket, PacketHandler>::Create(int) <null> (pdns_server+0x1f632ea)
    #5 qthread $HOME/gandi/pdns/pdns/common_startup.cc:472 (pdns_server+0x1f48c93)
    #6 void std::__invoke_impl<void, void (*)(unsigned int), unsigned int>(std::__invoke_other, void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9df26)
    #7 std::__invoke_result<void (*)(unsigned int), unsigned int>::type std::__invoke<void (*)(unsigned int), unsigned int>(void (*&&)(unsigned int), unsigned int&&) <null> (pdns_server+0x1f9c4d5)
    #8 void std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) <null> (pdns_server+0x1f9a696)
    #9 std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> >::operator()() <null> (pdns_server+0x1f93d5e)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(unsigned int), unsigned int> > >::_M_run() /usr/include/c++/12.1.0/bits/std_thread.h:210 (pdns_server+0x1f905e3)
    #11 execute_native_thread_routine /usr/src/debug/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd6182)

SUMMARY: ThreadSanitizer: data race $HOME/gandi/pdns/pdns/common_startup.cc:459 in sendout

darnuria avatar Aug 02 '22 10:08 darnuria

Sorry did some edits to ease issue reading.

darnuria avatar Aug 02 '22 10:08 darnuria

Note that dnsdist and recursor define suppression entries for similar cases. The idea being that atomic updates are quite expensive and we don't care too much about these races for stats.

https://github.com/PowerDNS/pdns/blob/master/pdns/recursordist/recursor-tsan.supp https://github.com/PowerDNS/pdns/blob/master/pdns/dnsdistdist/dnsdist-tsan.supp

omoerbeek avatar Aug 02 '22 10:08 omoerbeek

No problem didn't see any issue (maybe not searched enough) about this, and didn't see the tsan.supp files thanks for pointing them, I will maybe end up with a contribution to contributing.md or developpement.md to add links to them.

Thanks for your time :)

Feel free to close!

darnuria avatar Aug 02 '22 10:08 darnuria

Maybe you can contribute an auth-tsan.supp? :)

Habbie avatar Aug 02 '22 10:08 Habbie

Will do it later (tonigh europe hours or tomorrow) I have maybe an other data race to report still have to figure if it's our pdns setup who trigger it or it's from master.

darnuria avatar Aug 02 '22 12:08 darnuria

Resolved by https://github.com/PowerDNS/pdns/pull/11819

darnuria avatar Aug 23 '22 08:08 darnuria