This repository has been archived by the owner on Jan 7, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix TSAN error in LifoEventSem shutdown
Summary: TSAN report: ================== WARNING: ThreadSanitizer: data race (pid=3276373) Write of size 8 at 0x7ba000000330 by thread T10: #0 close at ??:? #1 facebook::logdevice::detail::SynchronizationFd::~SynchronizationFd() at ./logdevice/common/LifoEventSem.cpp:59 #2 facebook::logdevice::detail::FdBaton<std::atomic>::~FdBaton() at ./logdevice/common/LifoEventSem.h:68 #3 std::default_delete<facebook::logdevice::detail::FdBaton<std::atomic> >::operator()(facebook::logdevice::detail::FdBaton<std::atomic>*) const at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/unique_ptr.h:78 #4 std::unique_ptr<facebook::logdevice::detail::FdBaton<std::atomic>, std::default_delete<facebook::logdevice::detail::FdBaton<std::atomic> > >::~unique_ptr() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/unique_ptr.h:268 #5 facebook::logdevice::detail::LifoFdBaton<std::atomic>::~LifoFdBaton() at ./logdevice/common/LifoEventSem.h:155 #6 folly::detail::LifoSemNode<facebook::logdevice::detail::LifoFdBaton<std::atomic>, std::atomic>::destroy() at ./folly/synchronization/LifoSem.h:195 #7 folly::detail::LifoSemNodeRecycler<facebook::logdevice::detail::LifoFdBaton<std::atomic>, std::atomic>::operator()(folly::detail::LifoSemNode<facebook::logdevice::detail::LifoFdBaton<std::atomic>, std::atomic>*) const at ./folly/synchronization/LifoSem.h:213 #8 std::unique_ptr<folly::detail::LifoSemNode<facebook::logdevice::detail::LifoFdBaton<std::atomic>, std::atomic>, folly::detail::LifoSemNodeRecycler<facebook::logdevice::detail::LifoFdBaton<std::atomic>, std::atomic> >::~unique_ptr() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/unique_ptr.h:268 #9 facebook::logdevice::LifoEventSemImpl<std::atomic>::AsyncWaiter::~AsyncWaiter() at ./logdevice/common/LifoEventSem.h:380 #10 facebook::logdevice::LifoEventSemImpl<std::atomic>::AsyncWaiter::~AsyncWaiter() at ./logdevice/common/LifoEventSem.h:358 #11 folly::DelayedDestruction::onDelayedDestroy(bool) at ./folly/io/async/DelayedDestruction.h:115 #12 folly::DelayedDestruction::destroy() at ./folly/io/async/DelayedDestruction.h:55 #13 folly::DelayedDestruction::Destructor::operator()(folly::DelayedDestruction*) const at ./folly/io/async/DelayedDestruction.h:70 #14 std::unique_ptr<facebook::logdevice::LifoEventSemImpl<std::atomic>::AsyncWaiter, folly::DelayedDestruction::Destructor>::reset(facebook::logdevice::LifoEventSemImpl<std::atomic>::AsyncWaiter*) at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/unique_ptr.h:376 #15 facebook::logdevice::EventLoopTaskQueue::haveTasksEventHandler() at ./logdevice/common/EventLoopTaskQueue.cpp:113 #16 facebook::logdevice::EventLoopTaskQueue::EventLoopTaskQueue(facebook::logdevice::EvBase&, unsigned long, std::array<unsigned int, 3ul> const&)::$_0::operator()() const at ./logdevice/common/EventLoopTaskQueue.cpp:36 #17 void folly::detail::function::FunctionTraits<void ()>::callSmall<facebook::logdevice::EventLoopTaskQueue::EventLoopTaskQueue(facebook::logdevice::EvBase&, unsigned long, std::array<unsigned int, 3ul> const&)::$_0>(folly::detail::function::Data&) at ./folly/Function.h:361 #18 folly::detail::function::FunctionTraits<void ()>::operator()() at ./folly/Function.h:377 #19 facebook::logdevice::EventLegacy::evCallback(int, short, void*) at ./logdevice/common/libevent/EventLegacy.cpp:41 #20 event_persist_closure at ./logdevice/external/libevent-2.1.3-alpha/event.c:1452 #21 event_process_active_single_queue at ./logdevice/external/libevent-2.1.3-alpha/event.c:1508 #22 event_process_active at ./logdevice/external/libevent-2.1.3-alpha/event.c:1596 #23 ld_event_base_loop at ./logdevice/external/libevent-2.1.3-alpha/event.c:1819 #24 facebook::logdevice::EvBaseLegacy::loop() at ./logdevice/common/libevent/EvBaseLegacy.cpp:58 #25 facebook::logdevice::EvBase::loop() at ./logdevice/common/libevent/LibEventCompatibility.cpp:52 #26 facebook::logdevice::EventLoop::run() at ./logdevice/common/EventLoop.cpp:140 #27 facebook::logdevice::EventLoop::EventLoop(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, facebook::logdevice::ThreadID::Type, unsigned long, bool, std::array<unsigned int, 3ul> const&, facebook::logdevice::EvBase::EvBaseType)::$_0::operator()() const at ./logdevice/common/EventLoop.cpp:81 #28 std::_Function_handler<void (), facebook::logdevice::EventLoop::EventLoop(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, facebook::logdevice::ThreadID::Type, unsigned long, bool, std::array<unsigned int, 3ul> const&, facebook::logdevice::EvBase::EvBaseType)::$_0>::_M_invoke(std::_Any_data const&) at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/std_function.h:316 #29 std::function<void ()>::operator()() const at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/std_function.h:706 #30 facebook::logdevice::thread_func(void*) at ./logdevice/common/PThread.cpp:9 #31 __tsan_thread_start_func at tsan.c:? Previous read of size 8 at 0x7ba000000330 by main thread: #0 write at ??:? #1 facebook::logdevice::detail::SynchronizationFd::write() at ./logdevice/common/LifoEventSem.cpp:75 #2 post at ./logdevice/common/LifoEventSem.h:72 #3 facebook::logdevice::EventLoopTaskQueue::shutdown() at ./logdevice/common/EventLoopTaskQueue.cpp:68 #4 facebook::logdevice::Processor::shutdown() at ./logdevice/common/Processor.cpp:585 #5 facebook::logdevice::ClientImpl::~ClientImpl() at ./logdevice/lib/ClientImpl.cpp:314 #6 void __gnu_cxx::new_allocator<facebook::logdevice::ClientImpl>::destroy<facebook::logdevice::ClientImpl>(facebook::logdevice::ClientImpl*) at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/ext/new_allocator.h:157 #7 void std::allocator_traits<std::allocator<facebook::logdevice::ClientImpl> >::destroy<facebook::logdevice::ClientImpl>(std::allocator<facebook::logdevice::ClientImpl>&, facebook::logdevice::ClientImpl*) at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/alloc_traits.h:488 #8 std::_Sp_counted_ptr_inplace<facebook::logdevice::ClientImpl, std::allocator<facebook::logdevice::ClientImpl>, (__gnu_cxx::_Lock_policy)2>::_M_dispose() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/shared_ptr_base.h:537 #9 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/shared_ptr_base.h:156 #10 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/shared_ptr_base.h:686 #11 std::__shared_ptr<facebook::logdevice::Client, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/shared_ptr_base.h:1125 #12 std::shared_ptr<facebook::logdevice::Client>::~shared_ptr() at ./third-party-buck/platform007/build/libgcc/include/c++/trunk/bits/shared_ptr.h:93 #13 SequencerIntegrationTest_ExpandShrinkReactivationDelayTest_Test::TestBody() at ./logdevice/test/SequencerIntegrationTest.cpp:580 #14 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) at /home/engshare/third-party2/googletest/master/src/googletest/googletest/src/gtest.cc:2417 #15 main at ./common/gtest/LightMain.cpp:19 #16 ?? ??:0 During shutdown, a write() to fd triggers the worker thread to wake up and destroy the same fd. So, technically, fd might be destroyed before the write() returns, while write() is still accessing the fd. This diff adds some synchronization to make sure fd close() starts only after write() returns. #thanks Nick Sukhanov for figuring that out. Reviewed By: mcrnic, tau0 Differential Revision: D18018223 fbshipit-source-id: ddbff95257dd39c835ad6e8733ba0bf2ed432fa0
- Loading branch information