Open
Description
In an application that uses a large number of threads, I can frequently reproduce a CHECK failed in Thread Sanitizer.
ThreadSanitizer: CHECK failed: sanitizer_thread_registry.cpp:186 "((live_.try_emplace(user_id, tid).second)) != (0)" (0x0, 0x0) (tid=50579)
#0 __tsan::CheckUnwind() ../../../../libsanitizer/tsan/tsan_rtl.cpp:676 (libtsan.so.2+0x6a63a) (BuildId: 51a623d990ea8c1d192774bb95a1b723606c1288)
#1 __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) <null> (libtsan.so.2+0xa504f) (BuildId: 51a623d990ea8c1d192774bb95a1b723606c1288)
#2 __sanitizer::ThreadRegistry::CreateThread(unsigned long, bool, unsigned int, unsigned int, void*) <null> (libtsan.so.2+0xa9cad) (BuildId: 51a623d990ea8c1d192774bb95a1b723606c1288)
#3 __tsan::ThreadCreate(__tsan::ThreadState*, unsigned long, unsigned long, bool) ../../../../libsanitizer/sanitizer_common/sanitizer_thread_registry.h:113 (libtsan.so.2+0x82136) (BuildId: 51a623d990ea8c1d192774bb95a1b723606c1288)
#4 pthread_create <null> (libtsan.so.2+0x1f4ed) (BuildId: 51a623d990ea8c1d192774bb95a1b723606c1288)
#5 g_system_thread_new ../glib/gthread-posix.c:762 (libglib-2.0.so.0+0x76a30) (BuildId: 2acd4dfbc176f0dd02c08005d3214bc81469bc57)
#6 g_thread_new_internal ../glib/gthread.c:997 (libglib-2.0.so.0+0x76a30)
#7 g_thread_new <null> (libglib-2.0.so.0+0x76c2d) (BuildId: 2acd4dfbc176f0dd02c08005d3214bc81469bc57)
#8 <null> <null> (libgstrtpmanager.so+0x137bb) (BuildId: e88f813782372b3b152ccf0a96c690f09b3e652b)
#9 gst_element_change_state <null> (libgstreamer-1.0.so.0+0x473b3) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#10 gst_element_set_state_func.lto_priv.0 <null> (libgstreamer-1.0.so.0+0x4796b) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#11 gst_bin_change_state_func <null> (libgstreamer-1.0.so.0+0x1c077) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#12 gst_pipeline_change_state <null> (libgstreamer-1.0.so.0+0x7981e) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#13 gst_element_change_state <null> (libgstreamer-1.0.so.0+0x473b3) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#14 gst_element_change_state <null> (libgstreamer-1.0.so.0+0x473fa) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
#15 gst_element_set_state_func.lto_priv.0 <null> (libgstreamer-1.0.so.0+0x4796b) (BuildId: 8c4e928d60fdc40f3b85e0049c507f274fa8fb7a)
If I understood correctly, the user_id
that is inserted into live_
in sanitizer_thread_registry.cpp is supposed to be the value of pthread_t that is passed by pointer to pthread_create
. The failing check reveals that a pthread_t
is already present in the map, as if the system may be attempting to assign the same pthread_t
to multiple concurrently running threads.
I can imagine that live_
is not cleaned up when a thread finishes using pthread_clockjoin_np
, which has been used by Qt's QThread since version 6.9, as there does not appear to be an interceptor set in tsan_interceptors_posix.cpp for pthread_clockjoin_np
.