Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-48816

TSan: Data race on CBStatCollector::addStat

    XMLWordPrintable

Details

    • Untriaged
    • 1
    • Unknown
    • KV 2021-Oct-21, KV 2021-Nov, KV 2021-Dec

    Description

      As seen during cluster_run on Ubuntu 18.04 with TSan enabled:

      WARNING: ThreadSanitizer: data race (pid=24371)
        Read of size 8 at 0x7b54000a2df0 by thread T62:
          #0 Cookie::getHeader() const kv_engine/daemon/cookie.cc:201 (memcached+0x6508ac)
          #1 append_stats kv_engine/daemon/protocol/mcbp/stats_context.cc:95 (memcached+0x71fd6c)
          #2 void std::__invoke_impl<void, void (...) /usr/include/c++/10/bits/invoke.h:60 (memcached+0x72b56f)
          #3 std::enable_if<...> /usr/include/c++/10/bits/invoke.h:110 (memcached+0x72b56f)
          #4 std::_Function_handler<...>::operator()(...) /usr/include/c++/10/bits/std_function.h:622 (memcached+0x8232ad)
          #6 void std::__invoke_impl<...> /usr/include/c++/10/bits/invoke.h:60 (memcached+0x8232ad)
          #7 std::__invoke_result<...> /usr/include/c++/10/bits/invoke.h:95 (memcached+0x8232ad)
          #8 std::result_of<...> /usr/include/c++/10/bits/refwrap.h:349 (memcached+0x8232ad)
          #9 _ZZNK19makeExitBorderGuardMUlOT_E_clISt17reference_wrapperIKSt8functionIFvSt17basic_string_viewIcSt11char_traitsIcEES8_PKvEEEEEDaS0_ENKUlDpOT_E_clIJS8_S8_SA_EEEDaSH_ kv_engine/engines/ep/src/ep_engine.cc:344 (memcached+0x8232ad)
          #10 _ZSt13__invoke_implIvRZNK19makeExitBorderGuardMUlOT_E_clISt17reference_wrapperIKSt8functionIFvSt17basic_string_viewIcSt11char_traitsIcEES9_PKvEEEEEDaS1_EUlDpOT_E_JS9_S9_SB_EES0_St14__invoke_otherOT0_DpOT1_ /usr/include/c++/10/bits/invoke.h:60 (memcached+0x8232ad)
          #11 _ZSt10__invoke_rIvRZNK19makeExitBorderGuardMUlOT_E_clISt17reference_wrapperIKSt8functionIFvSt17basic_string_viewIcSt11char_traitsIcEES9_PKvEEEEEDaS1_EUlDpOT_E_JS9_S9_SB_EENSt9enable_ifIX16is_invocable_r_vIS0_T0_DpT1_EES0_E4typeEOSM_DpOSN_ /usr/include/c++/10/bits/invoke.h:110 (memcached+0x8232ad)
          #12 _ZNSt17_Function_handlerIFvSt17basic_string_viewIcSt11char_traitsIcEES3_PKvEZNK19makeExitBorderGuardMUlOT_E_clISt17reference_wrapperIKSt8functionIS6_EEEEDaS8_EUlDpOT_E_E9_M_invokeERKSt9_Any_dataOS3_SO_OS5_ /usr/include/c++/10/bits/std_function.h:291 (memcached+0x8232ad)
          #13 std::function<void (std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void const*)>::operator()(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void const*) const /usr/include/c++/10/bits/std_function.h:622 (memcached+0xdd90c2)
          #14 CBStatCollector::addStat(cb::stats::StatDef const&, std::basic_string_view<char, std::char_traits<char> >, std::unordered_map<char const*, std::basic_string_view<char, std::char_traits<char> >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<char const* const, std::basic_string_view<char, std::char_traits<char> > > > > const&) const ../kv_engine/statistics/cbstat_collector.cc:43 (memcached+0xdd90c2)
          #15 CBStatCollector::addStat(cb::stats::StatDef const&, unsigned long, std::unordered_map<char const*, std::basic_string_view<char, std::char_traits<char> >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<char const* const, std::basic_string_view<char, std::char_traits<char> > > > > const&) const ../kv_engine/statistics/cbstat_collector.cc:66 (memcached+0xdd6c65)
          #16 void LabelledStatCollector::forwardToParent<unsigned long&>(cb::stats::StatDef const&, unsigned long&, std::unordered_map<char const*, std::basic_string_view<char, std::char_traits<char> >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<char const* const, std::basic_string_view<char, std::char_traits<char> > > > > const&) const ../kv_engine/include/statistics/labelled_collector.h:130 (memcached+0xddf5c2)
          #17 LabelledStatCollector::addStat(cb::stats::StatDef const&, unsigned long, std::unordered_map<char const*, std::basic_string_view<char, std::char_traits<char> >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<char const* const, std::basic_string_view<char, std::char_traits<char> > > > > const&) const ../kv_engine/statistics/labelled_collector.cc:64 (memcached+0xddf5c2)
          #18 void StatCollector::addStat<unsigned long const&>(cb::stats::Key, unsigned long const&, std::unordered_map<char const*, std::basic_string_view<char, std::char_traits<char> >, std::hash<std::basic_string_view<char, std::char_traits<char> > >, std::equal_to<std::basic_string_view<char, std::char_traits<char> > >, std::allocator<std::pair<char const* const, std::basic_string_view<char, std::char_traits<char> > > > > const&) const ../kv_engine/include/statistics/collector.h:326 (memcached+0x7e50e5)
          #19 void StatCollector::addStat<cb::stats::Key, unsigned long const&>(cb::stats::Key&&, unsigned long const&) const ../kv_engine/include/statistics/collector.h:336 (memcached+0x7e50e5)
          #20 EventuallyPersistentEngine::addAggregatedProducerStats(BucketStatCollector const&, ConnCounter const&) kv_engine/engines/ep/src/ep_engine.cc:4038 (memcached+0x7e50e5)
          #21 EventuallyPersistentEngine::doDcpStatsInner(CookieIface const*, std::function<void (std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, void const*)> const&, std::basic_string_view<char, std::char_traits<char> >) kv_engine/engines/ep/src/ep_engine.cc:4030 (memcached+0x81bd05)
          #22 operator() kv_engine/engines/ep/src/ep_engine.cc:4007 (memcached+0x81bf25)
          #23 __invoke_impl<cb::engine_errc, EventuallyPersistentEngine::doDcpStats(const CookieIface*, const AddStatFn&, std::string_view)::<lambda(EventuallyPersistentEngine*, const CookieIface*)>&, EventuallyPersistentEngine*, const CookieIface*> /usr/include/c++/10/bits/invoke.h:60 (memcached+0x81bf25)
          #24 __invoke_r<cb::engine_errc, EventuallyPersistentEngine::doDcpStats(const CookieIface*, const AddStatFn&, std::string_view)::<lambda(EventuallyPersistentEngine*, const CookieIface*)>&, EventuallyPersistentEngine*, const CookieIface*> /usr/include/c++/10/bits/invoke.h:113 (memcached+0x81bf25)
          #25 _M_invoke /usr/include/c++/10/bits/std_function.h:291 (memcached+0x81bf25)
          #26 std::function<cb::engine_errc (EventuallyPersistentEngine*, CookieIface const*)>::operator()(EventuallyPersistentEngine*, CookieIface const*) const /usr/include/c++/10/bits/std_function.h:622 (memcached+0x82a57c)
          #27 StatDCPTask::run() kv_engine/engines/ep/src/ep_engine.cc:3913 (memcached+0x82a57c)
          #28 GlobalTask::execute() kv_engine/executor/globaltask.cc:68 (memcached+0xdcd5ed)
          #29 FollyExecutorPool::TaskProxy::scheduleViaCPUPool()::{lambda()#2}::operator()() const kv_engine/executor/folly_executorpool.cc:189 (memcached+0xdcd5ed)
          #30 void folly::detail::function::FunctionTraits<void ()>::callSmall<FollyExecutorPool::TaskProxy::scheduleViaCPUPool()::{lambda()#2}>(folly::detail::function::Data&) tlm/deps/folly.exploded/include/folly/Function.h:387 (memcached+0xdce315)
          #31 folly::detail::function::FunctionTraits<void ()>::operator()() folly/Function.h:416 (memcached+0xfb15a3)
          #32 folly::ThreadPoolExecutor::runTask(std::shared_ptr<folly::ThreadPoolExecutor::Thread> const&, folly::ThreadPoolExecutor::Task&&) folly/executors/ThreadPoolExecutor.cpp:97 (memcached+0xfb15a3)
          #33 folly::CPUThreadPoolExecutor::threadRun(std::shared_ptr<folly::ThreadPoolExecutor::Thread>) folly/executors/CPUThreadPoolExecutor.cpp:265 (memcached+0xf8ce50)
          #34 void std::__invoke_impl<void, void (folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>), folly::ThreadPoolExecutor*&, std::shared_ptr<folly::ThreadPoolExecutor::Thread>&>(std::__invoke_memfun_deref, void (folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>), folly::ThreadPoolExecutor*&, std::shared_ptr<folly::ThreadPoolExecutor::Thread>&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/invoke.h:73 (memcached+0xfb8774)
          #35 std::__invoke_result<void (folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>), folly::ThreadPoolExecutor*&, std::shared_ptr<folly::ThreadPoolExecutor::Thread>&>::type std::__invoke<void (folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>), folly::ThreadPoolExecutor*&, std::shared_ptr<folly::ThreadPoolExecutor::Thread>&>(void (folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>), folly::ThreadPoolExecutor*&, std::shared_ptr<folly::ThreadPoolExecutor::Thread>&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/invoke.h:95 (memcached+0xfb8535)
          #36 void std::_Bind<void (folly::ThreadPoolExecutor::*(folly::ThreadPoolExecutor*, std::shared_ptr<folly::ThreadPoolExecutor::Thread>))(std::shared_ptr<folly::ThreadPoolExecutor::Thread>)>::__call<void, , 0ul, 1ul>(std::tuple<>&&, std::_Index_tuple<0ul, 1ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/functional:467 (memcached+0xfb8535)
          #37 void std::_Bind<void (folly::ThreadPoolExecutor::*(folly::ThreadPoolExecutor*, std::shared_ptr<folly::ThreadPoolExecutor::Thread>))(std::shared_ptr<folly::ThreadPoolExecutor::Thread>)>::operator()<, void>() /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/functional:549 (memcached+0xfb8535)
          #38 void folly::detail::function::FunctionTraits<void ()>::callBig<std::_Bind<void (folly::ThreadPoolExecutor::*(folly::ThreadPoolExecutor*, std::shared_ptr<folly::ThreadPoolExecutor::Thread>))(std::shared_ptr<folly::ThreadPoolExecutor::Thread>)> >(folly::detail::function::Data&) folly/Function.h:401 (memcached+0xfb8535)
          #39 folly::detail::function::FunctionTraits<void ()>::operator()() tlm/deps/folly.exploded/include/folly/Function.h:416 (memcached+0xdccd15)
          #40 CBRegisteredThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}::operator()() kv_engine/executor/folly_executorpool.cc:47 (memcached+0xdccd15)
          #41 void folly::detail::function::FunctionTraits<void ()>::callBig<CBRegisteredThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}>(folly::detail::function::Data&) tlm/deps/folly.exploded/include/folly/Function.h:401 (memcached+0xdccd15)
          #42 folly::detail::function::FunctionTraits<void ()>::operator()() tlm/deps/folly.exploded/include/folly/Function.h:416 (memcached+0xdcbd6b)
          #43 folly::PriorityThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}::operator()() tlm/deps/folly.exploded/include/folly/executors/thread_factory/PriorityThreadFactory.h:54 (memcached+0xdcbd6b)
          #44 void folly::detail::function::FunctionTraits<void ()>::callBig<folly::PriorityThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}>(folly::detail::function::Data&) tlm/deps/folly.exploded/include/folly/Function.h:401 (memcached+0xdcbd6b)
          #45 folly::detail::function::FunctionTraits<void ()>::operator()() tlm/deps/folly.exploded/include/folly/Function.h:416 (memcached+0xdcb6da)
          #46 folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}::operator()() tlm/deps/folly.exploded/include/folly/executors/thread_factory/NamedThreadFactory.h:40 (memcached+0xdcb6da)
          #47 void std::__invoke_impl<void, folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}>(std::__invoke_other, folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}&&) /usr/include/c++/10/bits/invoke.h:60 (memcached+0xdcb6da)
          #48 std::__invoke_result<folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}>::type std::__invoke<folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}>(folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}&&) /usr/include/c++/10/bits/invoke.h:95 (memcached+0xdcb6da)
          #49 void std::thread::_Invoker<std::tuple<folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/10/thread:264 (memcached+0xdcb6da)
          #50 std::thread::_Invoker<std::tuple<folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}> >::operator()() /usr/include/c++/10/thread:271 (memcached+0xdcb6da)
          #51 std::thread::_State_impl<std::thread::_Invoker<std::tuple<folly::NamedThreadFactory::newThread(folly::Function<void ()>&&)::{lambda()#1}> > >::_M_run() /usr/include/c++/10/thread:215 (memcached+0xdcb6da)
          #52 <null> <null> (libstdc++.so.6+0xd44bf)
       
        Previous write of size 8 at 0x7b54000a2df0 by thread T21 (mutexes: write M3843):
          #0 Cookie::setPacket(cb::mcbp::Header const&, bool) kv_engine/daemon/cookie.cc:186 (memcached+0x65080e)
          #1 Cookie::preserveRequest() kv_engine/daemon/cookie.h:225 (memcached+0x696aa7)
          #2 Connection::executeCommandPipeline() kv_engine/daemon/connection.cc:581 (memcached+0x696aa7)
          #3 Connection::executeCommandsCallback() kv_engine/daemon/connection.cc:793 (memcached+0x696be8)
          #4 Connection::rw_callback(bufferevent*, void*) kv_engine/daemon/connection.cc:942 (memcached+0x697851)
          #5 bufferevent_run_deferred_callbacks_unlocked /home/couchbase/jenkins/workspace/cbdeps-platform-build-old/deps/packages/build/libevent/libevent-prefix/src/libevent/bufferevent.c:208 (libevent_core-2.1.so.7+0xf71d)
          #6 folly::EventBase::loopBody(int, bool) folly/io/async/EventBase.cpp:397 (memcached+0xfc9b52)
          #7 folly::EventBase::loop() folly/io/async/EventBase.cpp:315 (memcached+0xfcb06b)
          #8 folly::EventBase::loopForever() folly/io/async/EventBase.cpp:538 (memcached+0xfcb06b)
          #9 worker_libevent kv_engine/daemon/thread.cc:115 (memcached+0x6c16af)
          #10 CouchbaseThread::run() platform/src/cb_pthreads.cc:51 (memcached+0xf217d5)
          #11 platform_thread_wrap platform/src/cb_pthreads.cc:64 (memcached+0xf217d5)
      

      Observed while testing http://review.couchbase.org/c/kv_engine/+/162102/10, but I don't think is related to that.

      Seems that we are not taking the Cookie mutex when Cookie::getHeader() is called from the background NonIO thread which is executing StatDCPTask::run(). Possibly related to MB-38978 (gather DCP stats in background task) - but not confirmed.

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              drigby Dave Rigby (Inactive)
              drigby Dave Rigby (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes

                  PagerDuty