[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 --- Comment #10 from Jonathan Wakely --- We even have tests for the bogus tsan errors: g++.dg/tsan/pthread_cond_clockwait.C (which fails on machines with an old glibc)
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 --- Comment #9 from Jonathan Wakely --- The new interceptor was merged as g:d0fee87e0ce24f066cde3dbf9605abce24dd75e1
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 --- Comment #8 from Jakob Weisblat --- @Andrew: (In reply to Andrew Pinski from comment #7) Thanks! I'll try upgrading to GCC 12 to see if my issues go away.
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 --- Comment #7 from Andrew Pinski --- (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.
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 Jakob Weisblat changed: What|Removed |Added CC||jakob.weisblat at zoom dot us --- Comment #6 from Jakob Weisblat --- 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)
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 lewis pringle changed: What|Removed |Added CC||lewis at sophists dot com --- Comment #5 from lewis pringle --- 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 (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() (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...
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 Boris Kolpackov changed: What|Removed |Added CC||boris at kolpackov dot net --- Comment #4 from Boris Kolpackov --- 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::lock() /usr/include/c++/11/bits/unique_lock.h:139 (libbuild2-0.15.0-a.0.ecfa0f59dab6.so+0x62c701) #4 std::unique_lock::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 /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.
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 Daniel Adamski changed: What|Removed |Added CC||danregister at poczta dot fm --- Comment #3 from Daniel Adamski --- (g++ (Debian 11.2.0-14) 11.2.0) I believe it is wait_for() in particular. This works fine: #include #include #include #include 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::lock() /usr/include/c++/11/bits/unique_lock.h:139 (a.out+0x422d) #4 std::unique_lock::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(std::__invoke_other, void (*&&)()) /usr/include/c++/11/bits/invoke.h:61 (a.out+0x5550) #7 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/include/c++/11/bits/invoke.h:96 (a.out+0x54b5) #8 void std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/11/bits/std_thread.h:253 (a.out+0x541a) #9 std::thread::_Invoker >::operator()() /usr/include/c++/11/bits/std_thread.h:260 (a.out+0x53c4) #10 std::thread::_State_impl > >::_M_run() /usr/include/c++/11/bits/std_thread.h:211 (a.out+0x537e) #11 (libstdc++.so.6+0xd38f3) Location is global 'mtx' of size 40 at 0x56501849e160 (a.out+0x9160) 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::lock() /usr/include/c++/11/bits/unique_lock.h:139 (a.out+0x422d) #4 std::unique_lock::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(std::__invoke_other, void (*&&)()) /usr/include/c++/11/bits/invoke.h:61 (a.out+0x5550) #7 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/include/c++/11/bits/invoke.h:96 (a.out+0x54b5) #8 void std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/include/c++/11/bits/std_thread.h:253 (a.out+0x541a) #9 std::thread::_Invoker >::operator()() /usr/include/c++/11/bits/std_thread.h:260 (a.out+0x53c4) #10 std::thread::_State_impl > >::_M_run() /usr/include/c++/11/bits/std_thread.h:211 (a.out+0x537e) #11 (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
[Bug sanitizer/101978] thread sanitizer false positive when condition variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101978 Martin Liška changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2021-08-20 Ever confirmed|0 |1 --- Comment #2 from Martin Liška --- Confirmed.