hello.cpp 的内容
#include <gtkmm.h>
void RunInMain()
{
printf("RunInMain\n");
}
void ThreadFunc()
{
printf("ThreadFunc\n");
Glib::signal_idle().connect_once(std::bind(&RunInMain));
}
int main()
{
Gtk::Main kit(0, NULL);
Gtk::Window window;
window.set_title("hello world");
Glib::Thread* pThread = Glib::Thread::create(&ThreadFunc);
kit.run(window);
pThread->join();
return(0);
}
编译:
g++ `pkg-config gtkmm-2.4 --cflags --libs` hello.cpp -Wno-deprecated-declarations -fsanitize=thread
这是执行生成的 a.out 文件时来自 TSAN 的错误:
WARNING: ThreadSanitizer: data race (pid=153699)
Write of size 8 at 0x7b5000006f90 by thread T1:
#0 memset <null> (libtsan.so.0+0x37abf)
#1 g_slice_alloc0 <null> (libglib-2.0.so.0+0x71412)
#2 sigc::pointer_functor0<void>::operator()() const <null> (a.out+0x402835)
#3 sigc::adaptor_functor<sigc::pointer_functor0<void> >::operator()() const <null> (a.out+0x402606)
#4 sigc::internal::slot_call0<void (*)(), void>::call_it(sigc::internal::slot_rep*) <null> (a.out+0x4021d0)
#5 call_thread_entry_slot /usr/include/sigc++-2.0/sigc++/functors/slot.h:535 (libglibmm-2.4.so.1+0x5d889)
Previous write of size 8 at 0x7b5000006f90 by main thread:
#0 posix_memalign <null> (libtsan.so.0+0x3061d)
#1 allocator_memalign ../glib/gslice.c:1411 (libglib-2.0.so.0+0x706b8)
#2 allocator_add_slab ../glib/gslice.c:1283 (libglib-2.0.so.0+0x706b8)
#3 slab_allocator_alloc_chunk ../glib/gslice.c:1329 (libglib-2.0.so.0+0x706b8)
#4 __libc_start_main ../csu/libc-start.c:308 (libc.so.6+0x27041)
Location is heap block of size 496 at 0x7b5000006e00 allocated by main thread:
#0 posix_memalign <null> (libtsan.so.0+0x3061d)
#1 allocator_memalign ../glib/gslice.c:1411 (libglib-2.0.so.0+0x706b8)
#2 allocator_add_slab ../glib/gslice.c:1283 (libglib-2.0.so.0+0x706b8)
#3 slab_allocator_alloc_chunk ../glib/gslice.c:1329 (libglib-2.0.so.0+0x706b8)
#4 __libc_start_main ../csu/libc-start.c:308 (libc.so.6+0x27041)
Thread T1 (tid=153701, running) created by main thread at:
#0 pthread_create <null> (libtsan.so.0+0x5ec29)
#1 g_system_thread_new ../glib/gthread-posix.c:1308 (libglib-2.0.so.0+0xa0ea0)
#2 __libc_start_main ../csu/libc-start.c:308 (libc.so.6+0x27041)
SUMMARY: ThreadSanitizer: data race (/lib64/libtsan.so.0+0x37abf) in memset
代码按预期运行(我得到了所有的打印),但我不明白为什么我会收到 TSAN 数据竞争警告。如果我注释掉Glib::signal_idle().connect_once行,则没有 TSAN 错误。根据我的阅读,该函数应该可以安全地从任何线程调用。TSAN 是在此处报告误报还是存在真正的数据竞争?
Fedora 31 linux
g++ 10.0.1
glibmm24-2.64.2-1
gtkmm24-2.24.5-9
libtsan-10.2.1-9