public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers
@ 2021-08-19 14:31 ispavlick at gmail dot com
  2021-08-19 16:59 ` [Bug sanitizer/101978] " ispavlick at gmail dot com
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: ispavlick at gmail dot com @ 2021-08-19 14:31 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

            Bug ID: 101978
           Summary: thread sanitizer false positive when smart pointers
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ispavlick at gmail dot com
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---

When it is compiled with clang then no warnings are displayed (from sanitizer).

#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>
#include <queue>
#include <memory>
using namespace std;

struct Mes {
        int data = 0;
        bool processed = false;
};
struct Test {
        mutex mtx;
        condition_variable cv;
        queue<weak_ptr<Mes>> mes_queue;
        int read();
        bool check();
} t;
int Test::read() {
        auto sh_ptr = make_shared<Mes>();
        unique_lock lck{mtx};
        mes_queue.push(sh_ptr);
        while (! cv.wait_for(lck, 1s, [&sh_ptr](){
                                return sh_ptr->processed == true;})  &&  true);
        return sh_ptr->data;
}
bool Test::check() {
        unique_lock lck{mtx};
        bool ret = mes_queue.size();
        while (mes_queue.size()) {
                if (shared_ptr<Mes> mes = mes_queue.front().lock()) {
                        mes->data = 5;
                        mes->processed = true;
                }
                mes_queue.pop();
        }
        cv.notify_all();
        return ret;
}
void read_th() {
        while (true) {
                t.read();
                this_thread::sleep_for(200ms);
        }
}
void check_th() {
        while (true) {
                t.check();
                this_thread::sleep_for(200ms);
        }
}
int main() {
        jthread tr{read_th};
        jthread tc{check_th};
}

$ g++ -pthread -std=c++20 -fsanitize=thread test.cc
$ ./a.out

==================
WARNING: ThreadSanitizer: double lock of a mutex (pid=76697)
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::check() <null> (a.out+0x2628)
    #6 check_th() <null> (a.out+0x27d7)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is global 't' of size 168 at 0x562d5860c1c0 (a.out+0x0000000111c0)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

SUMMARY: ThreadSanitizer: double lock of a mutex (/tmp/a.out+0x2df5) in
__gthread_mutex_lock(pthread_mutex_t*)
==================
==================
WARNING: ThreadSanitizer: data race (pid=76697)
  Read of size 8 at 0x562d5860c248 by thread T2 (mutexes: write M10):
    #0 std::operator-(std::_Deque_iterator<std::weak_ptr<Mes>,
std::weak_ptr<Mes>&, std::weak_ptr<Mes>*> const&,
std::_Deque_iterator<std::weak_ptr<Mes>, std::weak_ptr<Mes>&,
std::weak_ptr<Mes>*> const&) <null> (a.out+0x6ba3)
    #1 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::size() const <null> (a.out+0x5cad)
    #2 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::size() const <null> (a.out+0x4c20)
    #3 Test::check() <null> (a.out+0x2638)
    #4 check_th() <null> (a.out+0x27d7)
    #5 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #6 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #7 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #8 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #9 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #10 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Previous write of size 8 at 0x562d5860c248 by thread T1 (mutexes: write M10):
    #0 std::weak_ptr<Mes>& std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > >::emplace_back<std::weak_ptr<Mes>
>(std::weak_ptr<Mes>&&) <null> (a.out+0x6896)
    #1 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::push_back(std::weak_ptr<Mes>&&) <null> (a.out+0x5992)
    #2 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::push(std::weak_ptr<Mes>&&) <null>
(a.out+0x4b77)
    #3 Test::read() <null> (a.out+0x24fa)
    #4 read_th() <null> (a.out+0x277a)
    #5 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #6 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #7 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #8 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #9 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #10 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is global 't' of size 168 at 0x562d5860c1c0 (a.out+0x000000011248)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Thread T2 (tid=76700, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x2851)

  Thread T1 (tid=76699, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x283b)

SUMMARY: ThreadSanitizer: data race (/tmp/a.out+0x6ba3) in
std::operator-(std::_Deque_iterator<std::weak_ptr<Mes>, std::weak_ptr<Mes>&,
std::weak_ptr<Mes>*> const&, std::_Deque_iterator<std::weak_ptr<Mes>,
std::weak_ptr<Mes>&, std::weak_ptr<Mes>*> const&)
==================
==================
WARNING: ThreadSanitizer: data race (pid=76697)
  Read of size 8 at 0x7b5000000008 by thread T2 (mutexes: write M10):
    #0
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2>
const&, std::nothrow_t) <null> (a.out+0x7b82)
    #1 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t) <null> (a.out+0x6c8b)
    #2 std::shared_ptr<Mes>::shared_ptr(std::weak_ptr<Mes> const&,
std::nothrow_t) <null> (a.out+0x5d5c)
    #3 std::weak_ptr<Mes>::lock() const <null> (a.out+0x4c9a)
    #4 Test::check() <null> (a.out+0x2668)
    #5 check_th() <null> (a.out+0x27d7)
    #6 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #7 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #8 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #9 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #11 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Previous write of size 8 at 0x7b5000000008 by thread T1 (mutexes: write M10):
    #0
std::__weak_count<(__gnu_cxx::_Lock_policy)2>::__weak_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2>&&)
<null> (a.out+0x8c0d)
    #1 std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__weak_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>&&) <null> (a.out+0x8387)
    #2 std::weak_ptr<Mes>::weak_ptr(std::weak_ptr<Mes>&&) <null> (a.out+0x75f0)
    #3 decltype (::new ((void*)(0))
std::weak_ptr<Mes>((declval<std::weak_ptr<Mes> >)()))
std::construct_at<std::weak_ptr<Mes>, std::weak_ptr<Mes> >(std::weak_ptr<Mes>*,
std::weak_ptr<Mes>&&) <null> (a.out+0x7645)
    #4 void std::allocator_traits<std::allocator<std::weak_ptr<Mes> >
>::construct<std::weak_ptr<Mes>, std::weak_ptr<Mes>
>(std::allocator<std::weak_ptr<Mes> >&, std::weak_ptr<Mes>*,
std::weak_ptr<Mes>&&) <null> (a.out+0x7694)
    #5 std::weak_ptr<Mes>& std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > >::emplace_back<std::weak_ptr<Mes>
>(std::weak_ptr<Mes>&&) <null> (a.out+0x686a)
    #6 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::push_back(std::weak_ptr<Mes>&&) <null> (a.out+0x5992)
    #7 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::push(std::weak_ptr<Mes>&&) <null>
(a.out+0x4b77)
    #8 Test::read() <null> (a.out+0x24fa)
    #9 read_th() <null> (a.out+0x277a)
    #10 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #11 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #12 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #13 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #14 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #15 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is heap block of size 512 at 0x7b5000000000 allocated by main
thread:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::weak_ptr<Mes> >::allocate(unsigned long,
void const*) <null> (a.out+0x999e)
    #2 std::allocator_traits<std::allocator<std::weak_ptr<Mes> >
>::allocate(std::allocator<std::weak_ptr<Mes> >&, unsigned long) <null>
(a.out+0x87d8)
    #3 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_allocate_node() <null> (a.out+0x804c)
    #4 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_create_nodes(std::weak_ptr<Mes>**, std::weak_ptr<Mes>**) <null>
(a.out+0x71c6)
    #5 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_initialize_map(unsigned long) <null> (a.out+0x61d5)
    #6 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_Deque_base() <null> (a.out+0x53b3)
    #7 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::deque() <null> (a.out+0x47ca)
    #8 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::queue<std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > >, void>() <null> (a.out+0x4874)
    #9 Test::Test() <null> (a.out+0x3eec)
    #10 __static_initialization_and_destruction_0(int, int) <null>
(a.out+0x2a52)
    #11 _GLOBAL__sub_I_t <null> (a.out+0x2ab4)
    #12 __libc_csu_init <null> (a.out+0xa64c)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Thread T2 (tid=76700, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x2851)

  Thread T1 (tid=76699, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x283b)

SUMMARY: ThreadSanitizer: data race (/tmp/a.out+0x7b82) in
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2>
const&, std::nothrow_t)
==================
==================
WARNING: ThreadSanitizer: data race (pid=76697)
  Atomic read of size 4 at 0x7b0800001028 by thread T2 (mutexes: write M10):
    #0 __tsan_atomic32_load
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interface_atomic.cpp:534
(libtsan.so.0+0x81eaf)
    #1 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_get_use_count()
const <null> (a.out+0x473f)
    #2
std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_add_ref_lock_nothrow()
<null> (a.out+0x3d31)
    #3
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count(std::__weak_count<(__gnu_cxx::_Lock_policy)2>
const&, std::nothrow_t) <null> (a.out+0x7bcf)
    #4 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t) <null> (a.out+0x6c8b)
    #5 std::shared_ptr<Mes>::shared_ptr(std::weak_ptr<Mes> const&,
std::nothrow_t) <null> (a.out+0x5d5c)
    #6 std::weak_ptr<Mes>::lock() const <null> (a.out+0x4c9a)
    #7 Test::check() <null> (a.out+0x2668)
    #8 check_th() <null> (a.out+0x27d7)
    #9 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #10 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #11 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #12 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #14 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Previous write of size 8 at 0x7b0800001028 by thread T1:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long,
void const*) <null> (a.out+0x9c51)
    #2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>::allocate(std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) <null>
(a.out+0x943a)
    #3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> > >
std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>(std::allocator<std::_Sp_counted_ptr_inplace<Mes, std::allocator<Mes>,
(__gnu_cxx::_Lock_policy)2> >&) <null> (a.out+0x88dc)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Mes,
std::allocator<Mes>>(Mes*&, std::_Sp_alloc_shared_tag<std::allocator<Mes> >)
<null> (a.out+0x8215)
    #5 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x74b8)
    #6
std::shared_ptr<Mes>::shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x6739)
    #7 std::shared_ptr<Mes> std::allocate_shared<Mes,
std::allocator<Mes>>(std::allocator<Mes> const&) <null> (a.out+0x5646)
    #8 std::shared_ptr<Mes> std::make_shared<Mes>() <null> (a.out+0x497c)
    #9 Test::read() <null> (a.out+0x24bd)
    #10 read_th() <null> (a.out+0x277a)
    #11 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #12 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #13 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #14 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #16 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is heap block of size 24 at 0x7b0800001020 allocated by thread T1:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long,
void const*) <null> (a.out+0x9c51)
    #2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>::allocate(std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) <null>
(a.out+0x943a)
    #3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> > >
std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>(std::allocator<std::_Sp_counted_ptr_inplace<Mes, std::allocator<Mes>,
(__gnu_cxx::_Lock_policy)2> >&) <null> (a.out+0x88dc)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Mes,
std::allocator<Mes>>(Mes*&, std::_Sp_alloc_shared_tag<std::allocator<Mes> >)
<null> (a.out+0x8215)
    #5 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x74b8)
    #6
std::shared_ptr<Mes>::shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x6739)
    #7 std::shared_ptr<Mes> std::allocate_shared<Mes,
std::allocator<Mes>>(std::allocator<Mes> const&) <null> (a.out+0x5646)
    #8 std::shared_ptr<Mes> std::make_shared<Mes>() <null> (a.out+0x497c)
    #9 Test::read() <null> (a.out+0x24bd)
    #10 read_th() <null> (a.out+0x277a)
    #11 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #12 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #13 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #14 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #16 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Thread T2 (tid=76700, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x2851)

  Thread T1 (tid=76699, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x283b)

SUMMARY: ThreadSanitizer: data race (/tmp/a.out+0x473f) in
std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_get_use_count() const
==================
==================
WARNING: ThreadSanitizer: data race (pid=76697)
  Read of size 8 at 0x7b5000000000 by thread T2 (mutexes: write M10):
    #0 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t) <null> (a.out+0x6cac)
    #1 std::shared_ptr<Mes>::shared_ptr(std::weak_ptr<Mes> const&,
std::nothrow_t) <null> (a.out+0x5d5c)
    #2 std::weak_ptr<Mes>::lock() const <null> (a.out+0x4c9a)
    #3 Test::check() <null> (a.out+0x2668)
    #4 check_th() <null> (a.out+0x27d7)
    #5 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #6 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #7 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #8 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #9 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #10 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Previous write of size 8 at 0x7b5000000000 by thread T1 (mutexes: write M10):
    #0 std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__weak_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>&&) <null> (a.out+0x835d)
    #1 std::weak_ptr<Mes>::weak_ptr(std::weak_ptr<Mes>&&) <null> (a.out+0x75f0)
    #2 decltype (::new ((void*)(0))
std::weak_ptr<Mes>((declval<std::weak_ptr<Mes> >)()))
std::construct_at<std::weak_ptr<Mes>, std::weak_ptr<Mes> >(std::weak_ptr<Mes>*,
std::weak_ptr<Mes>&&) <null> (a.out+0x7645)
    #3 void std::allocator_traits<std::allocator<std::weak_ptr<Mes> >
>::construct<std::weak_ptr<Mes>, std::weak_ptr<Mes>
>(std::allocator<std::weak_ptr<Mes> >&, std::weak_ptr<Mes>*,
std::weak_ptr<Mes>&&) <null> (a.out+0x7694)
    #4 std::weak_ptr<Mes>& std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > >::emplace_back<std::weak_ptr<Mes>
>(std::weak_ptr<Mes>&&) <null> (a.out+0x686a)
    #5 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::push_back(std::weak_ptr<Mes>&&) <null> (a.out+0x5992)
    #6 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::push(std::weak_ptr<Mes>&&) <null>
(a.out+0x4b77)
    #7 Test::read() <null> (a.out+0x24fa)
    #8 read_th() <null> (a.out+0x277a)
    #9 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #10 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #11 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #12 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #14 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is heap block of size 512 at 0x7b5000000000 allocated by main
thread:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::weak_ptr<Mes> >::allocate(unsigned long,
void const*) <null> (a.out+0x999e)
    #2 std::allocator_traits<std::allocator<std::weak_ptr<Mes> >
>::allocate(std::allocator<std::weak_ptr<Mes> >&, unsigned long) <null>
(a.out+0x87d8)
    #3 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_allocate_node() <null> (a.out+0x804c)
    #4 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_create_nodes(std::weak_ptr<Mes>**, std::weak_ptr<Mes>**) <null>
(a.out+0x71c6)
    #5 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_M_initialize_map(unsigned long) <null> (a.out+0x61d5)
    #6 std::_Deque_base<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::_Deque_base() <null> (a.out+0x53b3)
    #7 std::deque<std::weak_ptr<Mes>, std::allocator<std::weak_ptr<Mes> >
>::deque() <null> (a.out+0x47ca)
    #8 std::queue<std::weak_ptr<Mes>, std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > > >::queue<std::deque<std::weak_ptr<Mes>,
std::allocator<std::weak_ptr<Mes> > >, void>() <null> (a.out+0x4874)
    #9 Test::Test() <null> (a.out+0x3eec)
    #10 __static_initialization_and_destruction_0(int, int) <null>
(a.out+0x2a52)
    #11 _GLOBAL__sub_I_t <null> (a.out+0x2ab4)
    #12 __libc_csu_init <null> (a.out+0xa64c)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Thread T2 (tid=76700, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x2851)

  Thread T1 (tid=76699, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x283b)

SUMMARY: ThreadSanitizer: data race (/tmp/a.out+0x6cac) in
std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr(std::__weak_ptr<Mes,
(__gnu_cxx::_Lock_policy)2> const&, std::nothrow_t)
==================
==================
WARNING: ThreadSanitizer: data race (pid=76697)
  Write of size 4 at 0x7b0800001030 by thread T2 (mutexes: write M10):
    #0 Test::check() <null> (a.out+0x2692)
    #1 check_th() <null> (a.out+0x27d7)
    #2 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #3 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #4 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #5 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #6 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #7 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Previous write of size 8 at 0x7b0800001030 by thread T1:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long,
void const*) <null> (a.out+0x9c51)
    #2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>::allocate(std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) <null>
(a.out+0x943a)
    #3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> > >
std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>(std::allocator<std::_Sp_counted_ptr_inplace<Mes, std::allocator<Mes>,
(__gnu_cxx::_Lock_policy)2> >&) <null> (a.out+0x88dc)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Mes,
std::allocator<Mes>>(Mes*&, std::_Sp_alloc_shared_tag<std::allocator<Mes> >)
<null> (a.out+0x8215)
    #5 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x74b8)
    #6
std::shared_ptr<Mes>::shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x6739)
    #7 std::shared_ptr<Mes> std::allocate_shared<Mes,
std::allocator<Mes>>(std::allocator<Mes> const&) <null> (a.out+0x5646)
    #8 std::shared_ptr<Mes> std::make_shared<Mes>() <null> (a.out+0x497c)
    #9 Test::read() <null> (a.out+0x24bd)
    #10 read_th() <null> (a.out+0x277a)
    #11 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #12 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #13 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #14 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #16 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Location is heap block of size 24 at 0x7b0800001020 allocated by thread T1:
    #0 operator new(unsigned long)
/build/gcc/src/gcc/libsanitizer/tsan/tsan_new_delete.cpp:64
(libtsan.so.0+0x91824)
    #1 __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long,
void const*) <null> (a.out+0x9c51)
    #2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>::allocate(std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) <null>
(a.out+0x943a)
    #3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> > >
std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<Mes,
std::allocator<Mes>, (__gnu_cxx::_Lock_policy)2> >
>(std::allocator<std::_Sp_counted_ptr_inplace<Mes, std::allocator<Mes>,
(__gnu_cxx::_Lock_policy)2> >&) <null> (a.out+0x88dc)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<Mes,
std::allocator<Mes>>(Mes*&, std::_Sp_alloc_shared_tag<std::allocator<Mes> >)
<null> (a.out+0x8215)
    #5 std::__shared_ptr<Mes,
(__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x74b8)
    #6
std::shared_ptr<Mes>::shared_ptr<std::allocator<Mes>>(std::_Sp_alloc_shared_tag<std::allocator<Mes>
>) <null> (a.out+0x6739)
    #7 std::shared_ptr<Mes> std::allocate_shared<Mes,
std::allocator<Mes>>(std::allocator<Mes> const&) <null> (a.out+0x5646)
    #8 std::shared_ptr<Mes> std::make_shared<Mes>() <null> (a.out+0x497c)
    #9 Test::read() <null> (a.out+0x24bd)
    #10 read_th() <null> (a.out+0x277a)
    #11 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #12 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #13 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #14 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #16 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Mutex M10 (0x562d5860c1c0) created at:
    #0 pthread_mutex_lock
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4250
(libtsan.so.0+0x54b6a)
    #1 __gthread_mutex_lock(pthread_mutex_t*) <null> (a.out+0x2df5)
    #2 std::mutex::lock() <null> (a.out+0x2e7a)
    #3 std::unique_lock<std::mutex>::lock() <null> (a.out+0x56f5)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&) <null>
(a.out+0x4a32)
    #5 Test::read() <null> (a.out+0x24d0)
    #6 read_th() <null> (a.out+0x277a)
    #7 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) <null> (a.out+0xa562)
    #8 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) <null> (a.out+0xa4b9)
    #9 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>) <null> (a.out+0xa41e)
    #10 std::thread::_Invoker<std::tuple<void (*)()> >::operator()() <null>
(a.out+0xa3ae)
    #11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() <null> (a.out+0xa300)
    #12 execute_native_thread_routine
/build/gcc/src/gcc/libstdc++-v3/src/c++11/thread.cc:82 (libstdc++.so.6+0xd33c3)

  Thread T2 (tid=76700, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x2851)

  Thread T1 (tid=76699, running) created by main thread at:
    #0 pthread_create
/build/gcc/src/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:969
(libtsan.so.0+0x61c3a)
    #1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State,
std::default_delete<std::thread::_State> >, void (*)())
/build/gcc/src/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663
(libstdc++.so.6+0xd36aa)
    #2 std::thread std::jthread::_S_create<void (&)()>(std::stop_source&, void
(&)()) <null> (a.out+0x5ef2)
    #3 std::jthread::jthread<void (&)(), , void>(void (&)()) <null>
(a.out+0x4d9b)
    #4 main <null> (a.out+0x283b)

SUMMARY: ThreadSanitizer: data race (/tmp/a.out+0x2692) in Test::check()
==================

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when smart pointers
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
@ 2021-08-19 16:59 ` ispavlick at gmail dot com
  2021-08-20  7:53 ` [Bug sanitizer/101978] thread sanitizer false positive when condition variable marxin at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: ispavlick at gmail dot com @ 2021-08-19 16:59 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

--- Comment #1 from pavlick <ispavlick at gmail dot com> ---
Apparently this is due to condition_variable, if it is commented
        //while (! cv.wait_for(lck, 1s, [&sh_ptr](){
        //                      return sh_ptr->processed == true;})  &&  true);
then there are no warnings

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
  2021-08-19 16:59 ` [Bug sanitizer/101978] " ispavlick at gmail dot com
@ 2021-08-20  7:53 ` marxin at gcc dot gnu.org
  2022-02-20  6:04 ` danregister at poczta dot fm
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: marxin at gcc dot gnu.org @ 2021-08-20  7:53 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

Martin Liška <marxin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2021-08-20
     Ever confirmed|0                           |1

--- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> ---
Confirmed.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
  2021-08-19 16:59 ` [Bug sanitizer/101978] " ispavlick at gmail dot com
  2021-08-20  7:53 ` [Bug sanitizer/101978] thread sanitizer false positive when condition variable marxin at gcc dot gnu.org
@ 2022-02-20  6:04 ` danregister at poczta dot fm
  2022-07-18 11:35 ` boris at kolpackov dot net
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: danregister at poczta dot fm @ 2022-02-20  6:04 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

Daniel Adamski <danregister at poczta dot fm> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |danregister at poczta dot fm

--- Comment #3 from Daniel Adamski <danregister at poczta dot fm> ---
(g++ (Debian 11.2.0-14) 11.2.0)

I believe it is wait_for() in particular. This works fine:

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <thread>
using namespace std::chrono_literals;

std::mutex mtx;
std::condition_variable cv;

void run1() {
    std::unique_lock lck{mtx};
    cv.wait(lck);
}
void run2() {
    std::unique_lock lck{mtx};
    std::this_thread::sleep_for(500ms);
    cv.notify_all();
}
int main() {
    std::jthread th1{ run1 };
    std::jthread th2{ run2 };
}

But replace:

-    cv.wait(lck);
+    cv.wait_for(lck, 1s);

and you get "double lock":

==================
WARNING: ThreadSanitizer: double lock of a mutex (pid=644005)
    #0 pthread_mutex_lock
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4240
(libtsan.so.0+0x4f30a)
    #1 __gthread_mutex_lock
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749 (a.out+0x27bf)
    #2 std::mutex::lock() /usr/include/c++/11/bits/std_mutex.h:100
(a.out+0x2844)
    #3 std::unique_lock<std::mutex>::lock()
/usr/include/c++/11/bits/unique_lock.h:139 (a.out+0x422d)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&)
/usr/include/c++/11/bits/unique_lock.h:69 (a.out+0x3ce2)
    #5 run2() /tmp/tsanmy.cpp:16 (a.out+0x241d)
    #6 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) /usr/include/c++/11/bits/invoke.h:61 (a.out+0x5550)
    #7 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) /usr/include/c++/11/bits/invoke.h:96 (a.out+0x54b5)
    #8 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>)
/usr/include/c++/11/bits/std_thread.h:253 (a.out+0x541a)
    #9 std::thread::_Invoker<std::tuple<void (*)()> >::operator()()
/usr/include/c++/11/bits/std_thread.h:260 (a.out+0x53c4)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() /usr/include/c++/11/bits/std_thread.h:211 (a.out+0x537e)
    #11 <null> <null> (libstdc++.so.6+0xd38f3)

  Location is global 'mtx' of size 40 at 0x56501849e160 (a.out+0x000000009160)

  Mutex M10 (0x56501849e160) created at:
    #0 pthread_mutex_lock
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4240
(libtsan.so.0+0x4f30a)
    #1 __gthread_mutex_lock
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749 (a.out+0x27bf)
    #2 std::mutex::lock() /usr/include/c++/11/bits/std_mutex.h:100
(a.out+0x2844)
    #3 std::unique_lock<std::mutex>::lock()
/usr/include/c++/11/bits/unique_lock.h:139 (a.out+0x422d)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&)
/usr/include/c++/11/bits/unique_lock.h:69 (a.out+0x3ce2)
    #5 run1() /tmp/tsanmy.cpp:11 (a.out+0x2392)
    #6 void std::__invoke_impl<void, void (*)()>(std::__invoke_other, void
(*&&)()) /usr/include/c++/11/bits/invoke.h:61 (a.out+0x5550)
    #7 std::__invoke_result<void (*)()>::type std::__invoke<void (*)()>(void
(*&&)()) /usr/include/c++/11/bits/invoke.h:96 (a.out+0x54b5)
    #8 void std::thread::_Invoker<std::tuple<void (*)()>
>::_M_invoke<0ul>(std::_Index_tuple<0ul>)
/usr/include/c++/11/bits/std_thread.h:253 (a.out+0x541a)
    #9 std::thread::_Invoker<std::tuple<void (*)()> >::operator()()
/usr/include/c++/11/bits/std_thread.h:260 (a.out+0x53c4)
    #10 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)()> >
>::_M_run() /usr/include/c++/11/bits/std_thread.h:211 (a.out+0x537e)
    #11 <null> <null> (libstdc++.so.6+0xd38f3)

SUMMARY: ThreadSanitizer: double lock of a mutex
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749 in
__gthread_mutex_lock

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (2 preceding siblings ...)
  2022-02-20  6:04 ` danregister at poczta dot fm
@ 2022-07-18 11:35 ` boris at kolpackov dot net
  2022-07-28 15:36 ` lewis at sophists dot com
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: boris at kolpackov dot net @ 2022-07-18 11:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

Boris Kolpackov <boris at kolpackov dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |boris at kolpackov dot net

--- Comment #4 from Boris Kolpackov <boris at kolpackov dot net> ---
Reproduces with GCC 11.3.0 from Debian.

There is speculation on StackOverflow that links to this bug that this is
somehow causes by holding the mutex while calling notify_all(). But in our case
we get this bogus report without holding the mutex when calling notify_all().
Here is what the relevant parts in our code look like:

{
  unique_lock l (state_->mutex);
  state_->finished = true;
}

state_->condv.notify_all ();

And:

unique_lock l (state_->mutex);

if (!state_->finished &&
    !state_->condv.wait_for (l, tm, [state_] {return state_->finished;}))
  return nullopt;

Also, in our case we get two variants of this warning: as originally reported
and the second where the mutex is supposedly already destroyed (shown below).
Replacing wait_for() with wait() makes both disappear.

WARNING: ThreadSanitizer: double lock of a mutex (pid=1881)
    #0 pthread_mutex_lock
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4240
(libtsan.so.0+0x4f30a)
    #1 __gthread_mutex_lock
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:749
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x624ff5)
    #2 std::mutex::lock() /usr/include/c++/11/bits/std_mutex.h:100
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x625146)
    #3 std::unique_lock<std::mutex>::lock()
/usr/include/c++/11/bits/unique_lock.h:139
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x62c701)
    #4 std::unique_lock<std::mutex>::unique_lock(std::mutex&)
/usr/include/c++/11/bits/unique_lock.h:69
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x62c64c)
    #5 operator()
/tmp/bootstrap/build2-toolchain-0.15-a.0/libbutl-0.15.0-a.0.20220714150118.f07a6606e44d/libbutl/builtin.ixx:56
(libbutl-0.15.0-a.0.f07a6606e44d.so+0x24d443)
    ...

  Location is heap block of size 104 at 0x7b1c00017370 allocated by thread T9:
    #0 operator new(unsigned long)
../../../../src/libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.0+0x8857c)
    #1 async_impl
/tmp/bootstrap/build2-toolchain-0.15-a.0/libbutl-0.15.0-a.0.20220714150118.f07a6606e44d/libbutl/builtin.cxx:2191
(libbutl-0.15.0-a.0.f07a6606e44d.so+0x248ee8)
    #2 async_impl<butl::echo>
/tmp/bootstrap/build2-toolchain-0.15-a.0/libbutl-0.15.0-a.0.20220714150118.f07a6606e44d/libbutl/builtin.cxx:2205
(libbutl-0.15.0-a.0.f07a6606e44d.so+0x24db72)
    #3 run_pipe
/tmp/bootstrap/build2-toolchain-0.15-a.0/build2-0.15.0-a.0.20220717074539.ecfa0f59dab6/libbuild2/script/run.cxx:2160
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x82a1ec)
    #4 run_expr
/tmp/bootstrap/build2-toolchain-0.15-a.0/build2-0.15.0-a.0.20220717074539.ecfa0f59dab6/libbuild2/script/run.cxx:2492
(libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x82c409)
    ...

  Mutex M810501818139374456 is already destroyed.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (3 preceding siblings ...)
  2022-07-18 11:35 ` boris at kolpackov dot net
@ 2022-07-28 15:36 ` lewis at sophists dot com
  2022-09-23 14:52 ` jakob.weisblat at zoom dot us
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: lewis at sophists dot com @ 2022-07-28 15:36 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

lewis pringle <lewis at sophists dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lewis at sophists dot com

--- Comment #5 from lewis pringle <lewis at sophists dot com> ---
I have a (limited) trace of some of my code running into this problem. And even
without the code, the trace is strongly enough suggestive of where the problem
is I thought it worth including:

TSAN_OPTIONS="detect_deadlocks=0
suppressions=/Sandbox/Stroika-Dev//Tests/ThreadSanitizerSuppressions_qCompiler_SanitizerDoubleLockWithConditionVariables_Buggy.supp"
Builds/g++-debug-sanitize_thread/Tests/Test40
139746996119104] ENtering lock
139747039984064]ENtering try_lock_for
139747039984064]and the try_lock_for returned 0
139747039984064]ENtering try_lock_for
139747039984064]and the try_lock_for returned 0
139746996119104] Entering unlock
139747039984064]ENtering try_lock_for
139747039984064]and the try_lock_for returned 1
139747039984064] Entering unlock
==================
WARNING: ThreadSanitizer: unlock of an unlocked mutex (or by a wrong thread)
(pid=271643)
    #0 pthread_mutex_unlock <null> (Test40+0x8a4a88)
    #1 __gthread_mutex_unlock
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:779 (Test40+0x943790)
    #2 __gthread_recursive_mutex_unlock
/usr/include/x86_64-linux-gnu/c++/11/bits/gthr-default.h:832 (Test40+0x943800)
    #3 std::recursive_timed_mutex::unlock() <null> (Test40+0x97621d)
    #4 unlock /Sandbox/Stroika-Dev/Tests/40/Test.cpp:1380 (Test40+0x94ee9f)
    #5 unlock /usr/include/c++/11/bits/unique_lock.h:195 (Test40+0x968fed)
    #6 ~unique_lock /usr/include/c++/11/bits/unique_lock.h:104
(Test40+0x95f342)
    #7 ~ReadableReference
/Sandbox/Stroika-Dev/Library/Sources/Stroika/Foundation/Characters/../Execution/Synchronized.inl:447
(Test40+0x95849c)

it appears the problem is that (at least one) problem is that use of
try_lock_for () - when it acquires a lock - appears to not do the same
bookkeeping as lock, so that TSAN knows the lock happened and in what thread.
This COULD POSSIBLY be the same root cause of the problems with condition
variables (or maybe unrelated I suppose).

I dont know how TSAN does its magic/tracking, but I'd start looking at if
try_lock_for appears to similar stuff to lock...

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (4 preceding siblings ...)
  2022-07-28 15:36 ` lewis at sophists dot com
@ 2022-09-23 14:52 ` jakob.weisblat at zoom dot us
  2022-09-23 16:44 ` pinskia at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: jakob.weisblat at zoom dot us @ 2022-09-23 14:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

Jakob Weisblat <jakob.weisblat at zoom dot us> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakob.weisblat at zoom dot us

--- Comment #6 from Jakob Weisblat <jakob.weisblat at zoom dot us> ---
I think this is the same issue as
https://github.com/google/sanitizers/issues/1259. 

It was fixed in clang at
https://github.com/llvm/llvm-project/commit/16eb853ffdd1a1ad7c95455b7795c5f004402e46.

There exists an email that seems to indicate someone having submitted a GCC
patch to fix this issue, but I'm not really sure what the process is for
getting such a patch approved or included, and it seems to have been ignored:
https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568749.html (description)
/ https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568758.html (actual
patch)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (5 preceding siblings ...)
  2022-09-23 14:52 ` jakob.weisblat at zoom dot us
@ 2022-09-23 16:44 ` pinskia at gcc dot gnu.org
  2022-09-23 16:47 ` jakob.weisblat at zoom dot us
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-09-23 16:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Jakob Weisblat from comment #6)
> I think this is the same issue as
> https://github.com/google/sanitizers/issues/1259. 
> 
> It was fixed in clang at
> https://github.com/llvm/llvm-project/commit/
> 16eb853ffdd1a1ad7c95455b7795c5f004402e46.
> 
> There exists an email that seems to indicate someone having submitted a GCC
> patch to fix this issue, but I'm not really sure what the process is for
> getting such a patch approved or included, and it seems to have been
> ignored: https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568749.html
> (description) /
> https://gcc.gnu.org/pipermail/gcc-patches/2021-April/568758.html (actual
> patch)

If it is the same issue, then the fix went into GCC 12 with a (few) merge from
upstream.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (6 preceding siblings ...)
  2022-09-23 16:44 ` pinskia at gcc dot gnu.org
@ 2022-09-23 16:47 ` jakob.weisblat at zoom dot us
  2022-09-23 17:19 ` redi at gcc dot gnu.org
  2022-09-23 18:30 ` redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: jakob.weisblat at zoom dot us @ 2022-09-23 16:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

--- Comment #8 from Jakob Weisblat <jakob.weisblat at zoom dot us> ---
@Andrew: (In reply to Andrew Pinski from comment #7)

Thanks! I'll try upgrading to GCC 12 to see if my issues go away.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (7 preceding siblings ...)
  2022-09-23 16:47 ` jakob.weisblat at zoom dot us
@ 2022-09-23 17:19 ` redi at gcc dot gnu.org
  2022-09-23 18:30 ` redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2022-09-23 17:19 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The new interceptor was merged as g:d0fee87e0ce24f066cde3dbf9605abce24dd75e1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Bug sanitizer/101978] thread sanitizer false positive when condition variable
  2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
                   ` (8 preceding siblings ...)
  2022-09-23 17:19 ` redi at gcc dot gnu.org
@ 2022-09-23 18:30 ` redi at gcc dot gnu.org
  9 siblings, 0 replies; 11+ messages in thread
From: redi at gcc dot gnu.org @ 2022-09-23 18:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978

--- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> ---
We even have tests for the bogus tsan errors:
g++.dg/tsan/pthread_cond_clockwait.C

(which fails on machines with an old glibc)

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-09-23 18:30 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-19 14:31 [Bug sanitizer/101978] New: thread sanitizer false positive when smart pointers ispavlick at gmail dot com
2021-08-19 16:59 ` [Bug sanitizer/101978] " ispavlick at gmail dot com
2021-08-20  7:53 ` [Bug sanitizer/101978] thread sanitizer false positive when condition variable marxin at gcc dot gnu.org
2022-02-20  6:04 ` danregister at poczta dot fm
2022-07-18 11:35 ` boris at kolpackov dot net
2022-07-28 15:36 ` lewis at sophists dot com
2022-09-23 14:52 ` jakob.weisblat at zoom dot us
2022-09-23 16:44 ` pinskia at gcc dot gnu.org
2022-09-23 16:47 ` jakob.weisblat at zoom dot us
2022-09-23 17:19 ` redi at gcc dot gnu.org
2022-09-23 18:30 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).