【问题标题】:Gcc thread sanitizer false positive only for debug info flagGcc thread sanitizer false positive only for debug info flag
【发布时间】:2015-02-25 13:06:10
【问题描述】:

我在使用 Gcc 的线程清理程序时遇到问题,我无法在他们的 bugzilla 或 stackoverflow 上找到该问题,所以我不确定我是否遗漏了什么或者这是否真的是一个错误。如果我创建一个包含以下内容的 main.cpp 文件:

#include <thread>
int main(){
    std::thread t([](){});
    t.join();
    return 0;}

现在,如果我使用以下代码编译它:

g++-4.9.2 -std=c++1y -fsanitize=thread -fPIE -pie -o TestProgram main.cpp

运行生成的可执行文件不会产生任何问题。然而,如果我添加调试信息标志:

g++-4.9.2 -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp

然后线程清理器检测到数据竞争:

WARNING: ThreadSanitizer: data race (pid=22683)
  Write of size 8 at 0x7d0c0000efd8 by thread T1:
    #0 operator delete(void*) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:592 (libtsan.so.0+0x000000049490)
    #1 deallocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 (TestProgram+0x000000002089)
    #2 deallocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:383 (TestProgram+0x000000001f78)
    #3 _M_destroy /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:535 (TestProgram+0x0000000026f4)
    #4 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:166 (libstdc++.so.6+0x0000000b5c51)
    #5 ~__shared_count /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:666 (libstdc++.so.6+0x0000000b5c51)
    #6 ~__shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr_base.h:914 (libstdc++.so.6+0x0000000b5c51)
    #7 ~shared_ptr /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/shared_ptr.h:93 (libstdc++.so.6+0x0000000b5c51)
    #8 execute_native_thread_routine ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:95 (libstdc++.so.6+0x0000000b5c51)

  Previous atomic write of size 4 at 0x7d0c0000efd8 by main thread:
    #0 __tsan_atomic32_fetch_add ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interface_atomic.cc:468 (libtsan.so.0+0x0000000206ce)
    #1 __exchange_and_add /usr/local/include/c++/4.9.2/ext/atomicity.h:49 (TestProgram+0x0000000014a0)
    #2 __exchange_and_add_dispatch /usr/local/include/c++/4.9.2/ext/atomicity.h:82 (TestProgram+0x000000001557)
    #3 std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:146 (TestProgram+0x000000002ceb)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:666 (TestProgram+0x000000002cb6)
    #5 std::__shared_ptr<std::thread::_Impl_base, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:914 (TestProgram+0x000000002bc1)
    #6 std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() /usr/local/include/c++/4.9.2/bits/shared_ptr.h:93 (TestProgram+0x000000002bed)
    #7 thread<main()::<lambda()> > /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016f1)
    #8 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)

  Location is heap block of size 48 at 0x7d0c0000efd0 allocated by main thread:
    #0 operator new(unsigned long) ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:560 (libtsan.so.0+0x0000000496d2)
    #1 allocate /usr/local/include/c++/4.9.2/ext/new_allocator.h:104 (TestProgram+0x000000001fe9)
    #2 allocate /usr/local/include/c++/4.9.2/bits/alloc_traits.h:357 (TestProgram+0x000000001ecd)
    #3 __shared_count<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:616 (TestProgram+0x000000001d99)
    #4 __shared_ptr<std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr_base.h:1090 (TestProgram+0x000000001ccb)
    #5 shared_ptr<std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:316 (TestProgram+0x000000001c5f)
    #6 allocate_shared<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::allocator<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> > >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:588 (TestProgram+0x000000001bf0)
    #7 make_shared<std::thread::_Impl<std::_Bind_simple<main()::<lambda()>()> >, std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/bits/shared_ptr.h:604 (TestProgram+0x000000001ab0)
    #8 _M_make_routine<std::_Bind_simple<main()::<lambda()>()> > /usr/local/include/c++/4.9.2/thread:193 (TestProgram+0x000000001919)
    #9 thread<main()::<lambda()> > /usr/local/include/c++/4.9.2/thread:135 (TestProgram+0x0000000016bf)
    #10 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)

  Thread T1 (tid=22685, running) created by main thread at:
    #0 pthread_create ../../../../gcc-4.9.2/libsanitizer/tsan/tsan_interceptors.cc:877 (libtsan.so.0+0x000000047c03)
    #1 __gthread_create /home/UserG/Compile/objdir/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu/bits/gthr-default.h:662 (libstdc++.so.6+0x0000000b5d00)
    #2 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) ../../../../../gcc-4.9.2/libstdc++-v3/src/c++11/thread.cc:142 (libstdc++.so.6+0x0000000b5d00)
    #3 main /home/UserG/main.cpp:3 (TestProgram+0x0000000015af)

SUMMARY: ThreadSanitizer: data race /usr/local/include/c++/4.9.2/ext/new_allocator.h:110 deallocate
==================
ThreadSanitizer: reported 1 warnings

现在使用 clang++(版本 3.6.0(主干 221144))编译的完全相同的代码不会检测到数据竞争:

clang++ -std=c++1y -fsanitize=thread -g -fPIE -pie -o TestProgram main.cpp

我对 gcc 的这种行为有点好奇: 1) 将一个空的 lambda 函数作为参数传递给线程对我来说似乎是合法的 2) gcc 的行为取决于 -g 标志,我认为它与线程清理程序没有太大关系 3) 在类似的情况下,clang 采取了我认为正确的行为

非常感谢,

【问题讨论】:

  • 看来gcc 5.3.1 中已经修复了。编译时没有 -fPIE -pie 标志。

标签: c++ c++11 gcc sanitizer thread-sanitizer


【解决方案1】:

你的意思是this bug?据说是 4.8,但是a similar report exists for 4.9.2.

【讨论】:

  • 我认为你是对的,我专注于 -g 标志,我错过了明显的。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 2015-09-17
  • 2016-12-25
  • 1970-01-01
  • 2019-11-11
相关资源
最近更新 更多