Skip to content

Instantly share code, notes, and snippets.

@rettichschnidi
Last active October 5, 2016 10:36
Show Gist options
  • Save rettichschnidi/1c68ae6f40f14960f803 to your computer and use it in GitHub Desktop.
Save rettichschnidi/1c68ae6f40f14960f803 to your computer and use it in GitHub Desktop.
gcc TSAN fail
// Source: http://en.cppreference.com/w/cpp/thread/promise
#include <future>
#include <iostream>
#include <numeric>
#include <thread>
#include <vector>
void accumulate(std::vector<int>::iterator first,
std::vector<int>::iterator last,
std::promise<int> accumulate_promise) {
int sum = std::accumulate(first, last, 0);
accumulate_promise.set_value(sum); // Notify future
}
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
std::promise<int> accumulate_promise;
std::future<int> accumulate_future = accumulate_promise.get_future();
std::thread work_thread(accumulate, numbers.begin(), numbers.end(),
std::move(accumulate_promise));
accumulate_future.wait(); // wait for result
std::cout << "result=" << accumulate_future.get() << '\n';
work_thread.join(); // wait for thread completion
}
@rettichschnidi
Copy link
Author

reto@debian-rs:~/sensorcon-ng$ clang++-3.6 -v --std=c++11 -stdlib=libc++ -fsanitize=thread -pthread tsan-false-positive.cpp && ./a.out
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.8.5
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9.3
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/5.3.1
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8.5
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.8.5
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/5.3.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.3.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/usr/lib/llvm-3.6/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name tsan-false-positive.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.25.1 -v -dwarf-column-info -resource-dir /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2 -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include --std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/reto/sensorcon-ng -ferror-limit 19 -fmessage-length 211 -fsanitize=thread -pthread -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/tsan-false-positive-410c1b.o -x c++ tsan-false-positive.cpp
clang -cc1 version 3.6.2 based upon LLVM 3.6.2 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/v1
 /usr/local/include
 /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/usr/lib/x86_64-linux-gnu/../../lib64 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../.. -L/usr/lib/llvm-3.6/bin/../lib -L/lib -L/usr/lib -whole-archive /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/lib/linux/libclang_rt.tsan-x86_64.a -no-whole-archive -export-dynamic /tmp/tsan-false-positive-410c1b.o -lc++ -lm --no-as-needed -lpthread -lrt -lm -ldl -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crtn.o
==================
WARNING: ThreadSanitizer: data race (pid=29462)
  Write of size 8 at 0x7d200000bfc0 by main thread:
    #0 pthread_cond_destroy <null> (a.out+0x00000045d930)
    #1 std::__1::__assoc_sub_state::~__assoc_sub_state() <null> (a.out+0x0000004ca133)
    #2 std::__1::__assoc_state<int>::~__assoc_state() <null> (a.out+0x0000004c9f93)
    #3 std::__1::__assoc_state<int>::~__assoc_state() <null> (a.out+0x0000004c9fe7)
    #4 std::__1::__assoc_state<int>::__on_zero_shared() <null> (a.out+0x0000004ca098)
    #5 std::__1::__shared_count::__release_shared() <null> (libc++.so.1+0x0000000cc3d2)
    #6 std::__1::future<int>::get() <null> (a.out+0x0000004c30e2)
    #7 main <null> (a.out+0x0000004bf8e1)

  Previous read of size 8 at 0x7d200000bfc0 by thread T1:
    #0 pthread_cond_broadcast <null> (a.out+0x00000045d740)
    #1 void std::__1::__assoc_state<int>::set_value<int const&>(int const&) <null> (a.out+0x0000004cc91d)
    #2 std::__1::promise<int>::set_value(int const&) <null> (a.out+0x0000004bfe06)
    #3 accumulate(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>) <null> (a.out+0x0000004bedc1)
    #4 void* std::__1::__thread_proxy<std::__1::tuple<void (*)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int> > >(void*) <null> (a.out+0x0000004c899d)

  Location is heap block of size 120 at 0x7d200000bf80 allocated by main thread:
    #0 operator new(unsigned long) <null> (a.out+0x00000045922d)
    #1 std::__1::promise<int>::promise() <null> (a.out+0x0000004bfe9c)
    #2 main <null> (a.out+0x0000004bf493)

  Thread T1 (tid=29464, finished) created by main thread at:
    #0 pthread_create <null> (a.out+0x00000045c6d1)
    #1 std::__1::thread::thread<void (&)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>, void>(void (&)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>&&, std::__1::__wrap_iter<int*>&&, std::__1::promise<int>&&) <null> (a.out+0x0000004c1318)
    #2 main <null> (a.out+0x0000004bf85b)

SUMMARY: ThreadSanitizer: data race ??:0 __interceptor_pthread_cond_destroy
==================
==================
WARNING: ThreadSanitizer: data race (pid=29462)
  Write of size 8 at 0x7d200000bff0 by main thread:
    #0 operator delete(void*) <null> (a.out+0x0000004597db)
    #1 std::__1::__assoc_state<int>::~__assoc_state() <null> (a.out+0x0000004c9ff3)
    #2 std::__1::__assoc_state<int>::__on_zero_shared() <null> (a.out+0x0000004ca098)
    #3 std::__1::__shared_count::__release_shared() <null> (libc++.so.1+0x0000000cc3d2)
    #4 std::__1::future<int>::get() <null> (a.out+0x0000004c30e2)
    #5 main <null> (a.out+0x0000004bf8e1)

  Previous read of size 4 at 0x7d200000bff0 by thread T1:
    #0 std::__1::promise<int>::~promise() <null> (a.out+0x0000004c3563)
    #1 void* std::__1::__thread_proxy<std::__1::tuple<void (*)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int> > >(void*) <null> (a.out+0x0000004c8a46)

  Thread T1 (tid=29464, finished) created by main thread at:
    #0 pthread_create <null> (a.out+0x00000045c6d1)
    #1 std::__1::thread::thread<void (&)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>, void>(void (&)(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::promise<int>), std::__1::__wrap_iter<int*>&&, std::__1::__wrap_iter<int*>&&, std::__1::promise<int>&&) <null> (a.out+0x0000004c1318)
    #2 main <null> (a.out+0x0000004bf85b)

SUMMARY: ThreadSanitizer: data race ??:0 operator delete(void*)
==================
result=21
ThreadSanitizer: reported 2 warnings

@rettichschnidi
Copy link
Author

reto@debian-rs:~/sensorcon-ng$ g++-5 -v --std=c++11 -lstdc++ -fsanitize=thread -pthread tsan-false-positive.cpp && ./a.out
Using built-in specs.
COLLECT_GCC=g++-5
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 5.3.1-5' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.3.1 20160101 (Debian 5.3.1-5) 
COLLECT_GCC_OPTIONS='-v' '-std=c++11' '-fsanitize=thread' '-pthread' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE -D_REENTRANT tsan-false-positive.cpp -quiet -dumpbase tsan-false-positive.cpp -mtune=generic -march=x86-64 -auxbase tsan-false-positive -std=c++11 -version -fsanitize=thread -o /tmp/ccjnh7eD.s
GNU C++11 (Debian 5.3.1-5) version 5.3.1 20160101 (x86_64-linux-gnu)
    compiled by GNU C version 5.3.1 20160101, GMP version 6.1.0, MPFR version 3.1.3-p5, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/5"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/include/c++/5
 /usr/include/x86_64-linux-gnu/c++/5
 /usr/include/c++/5/backward
 /usr/lib/gcc/x86_64-linux-gnu/5/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C++11 (Debian 5.3.1-5) version 5.3.1 20160101 (x86_64-linux-gnu)
    compiled by GNU C version 5.3.1 20160101, GMP version 6.1.0, MPFR version 3.1.3-p5, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: b7665de381cba231667008f5b9d6a39a
COLLECT_GCC_OPTIONS='-v' '-std=c++11' '-fsanitize=thread' '-pthread' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccUXdn7U.o /tmp/ccjnh7eD.s
GNU assembler version 2.25.90 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.25.90.20160101
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-std=c++11' '-fsanitize=thread' '-pthread' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/5/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/5/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper -plugin-opt=-fresolution=/tmp/ccPlEqbd.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/5 -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/5/../../.. -ltsan -lstdc++ /tmp/ccUXdn7U.o -lstdc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crtn.o
==================
WARNING: ThreadSanitizer: data race (pid=29622)
  Read of size 8 at 0x7d0c0000efe8 by main thread:
    #0 std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::get() const <null> (a.out+0x00000040507b)
    #1 std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::operator*() const <null> (a.out+0x000000403ab6)
    #2 std::__future_base::_State_baseV2::wait() <null> (a.out+0x0000004031c1)
    #3 std::__basic_future<int>::wait() const <null> (a.out+0x000000404cb0)
    #4 main <null> (a.out+0x000000402486)

  Previous write of size 8 at 0x7d0c0000efe8 by thread T1:
    #0 void std::swap<std::__future_base::_Result_base*>(std::__future_base::_Result_base*&, std::__future_base::_Result_base*&) <null> (a.out+0x000000408727)
    #1 std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::_M_swap(std::_Tuple_impl<0ul, std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) <null> (a.out+0x000000407c1e)
    #2 std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>::swap(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) <null> (a.out+0x000000406cf8)
    #3 void std::swap<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>(std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&, std::tuple<std::__future_base::_Result_base*, std::__future_base::_Result_base::_Deleter>&) <null> (a.out+0x0000004051f0)
    #4 std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::swap(std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>&) <null> (a.out+0x000000403ff8)
    #5 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (a.out+0x000000403619)
    #6 void std::_Mem_fn_base<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), true>::operator()<std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*, void>(std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) const <null> (a.out+0x000000408686)
    #7 void std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) <null> (a.out+0x000000407bb5)
    #8 std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::operator()() <null> (a.out+0x000000406ca5)
    #9 void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> >() <null> (a.out+0x0000004051a0)
    #10 pthread_once <null> (libtsan.so.0+0x000000028a3f)
    #11 __gthread_once(int*, void (*)()) <null> (a.out+0x000000402109)
    #12 void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) <null> (a.out+0x000000403e9c)
    #13 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (a.out+0x0000004032c9)
    #14 std::promise<int>::set_value(int const&) <null> (a.out+0x00000040449f)
    #15 accumulate(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>) <null> (a.out+0x000000402381)
    #16 void std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) <null> (a.out+0x00000040acd4)
    #17 std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)>::operator()() <null> (a.out+0x00000040a9cd)
    #18 std::thread::_Impl<std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)> >::_M_run() <null> (a.out+0x00000040a758)
    #19 <null> <null> (libstdc++.so.6+0x0000000b728f)

  Location is heap block of size 48 at 0x7d0c0000efd0 allocated by main thread:
    #0 operator new(unsigned long) <null> (libtsan.so.0+0x000000025733)
    #1 __gnu_cxx::new_allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) <null> (a.out+0x000000409699)
    #2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) <null> (a.out+0x00000040920d)
    #3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> > >(std::allocator<std::_Sp_counted_ptr_inplace<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>, (__gnu_cxx::_Lock_policy)2> >&) <null> (a.out+0x000000408ce9)
    #4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::__future_base::_State_baseV2*, std::allocator<std::__future_base::_State_baseV2> const&) <null> (a.out+0x000000408829)
    #5 std::__shared_ptr<std::__future_base::_State_baseV2, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::allocator<std::__future_base::_State_baseV2> const&) <null> (a.out+0x000000407c9e)
    #6 std::shared_ptr<std::__future_base::_State_baseV2>::shared_ptr<std::allocator<std::__future_base::_State_baseV2>>(std::_Sp_make_shared_tag, std::allocator<std::__future_base::_State_baseV2> const&) <null> (a.out+0x000000406d84)
    #7 std::shared_ptr<std::__future_base::_State_baseV2> std::allocate_shared<std::__future_base::_State_baseV2, std::allocator<std::__future_base::_State_baseV2>>(std::allocator<std::__future_base::_State_baseV2> const&) <null> (a.out+0x000000405356)
    #8 std::shared_ptr<std::__future_base::_State_baseV2> std::make_shared<std::__future_base::_State_baseV2>() <null> (a.out+0x0000004041dc)
    #9 std::promise<int>::promise() <null> (a.out+0x00000040474a)
    #10 main <null> (a.out+0x000000402413)

  Thread T1 (tid=29624, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000026e74)
    #1 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void (*)()) <null> (libstdc++.so.6+0x0000000b73d2)
    #2 main <null> (a.out+0x000000402477)

SUMMARY: ThreadSanitizer: data race ??:0 std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>::get() const
==================
==================
WARNING: ThreadSanitizer: data race (pid=29622)
  Read of size 4 at 0x7d080000efb0 by main thread:
    #0 std::future<int>::get() <null> (a.out+0x000000404d32)
    #1 main <null> (a.out+0x000000402495)

  Previous write of size 4 at 0x7d080000efb0 by thread T1:
    #0 std::__future_base::_Result<int>::_M_set(int const&) <null> (a.out+0x000000408a0a)
    #1 std::__future_base::_State_baseV2::_Setter<int, int const&>::operator()() const <null> (a.out+0x000000407e6f)
    #2 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_State_baseV2::_Setter<int, int const&> >::_M_invoke(std::_Any_data const&) <null> (a.out+0x000000406eef)
    #3 std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>::operator()() const <null> (a.out+0x00000040405b)
    #4 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (a.out+0x0000004035ef)
    #5 void std::_Mem_fn_base<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), true>::operator()<std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*, void>(std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) const <null> (a.out+0x000000408686)
    #6 void std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) <null> (a.out+0x000000407bb5)
    #7 std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>::operator()() <null> (a.out+0x000000406ca5)
    #8 void std::__once_call_impl<std::_Bind_simple<std::_Mem_fn<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> (std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)> >() <null> (a.out+0x0000004051a0)
    #9 pthread_once <null> (libtsan.so.0+0x000000028a3f)
    #10 __gthread_once(int*, void (*)()) <null> (a.out+0x000000402109)
    #11 void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) <null> (a.out+0x000000403e9c)
    #12 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (a.out+0x0000004032c9)
    #13 std::promise<int>::set_value(int const&) <null> (a.out+0x00000040449f)
    #14 accumulate(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>) <null> (a.out+0x000000402381)
    #15 void std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)>::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) <null> (a.out+0x00000040acd4)
    #16 std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)>::operator()() <null> (a.out+0x00000040a9cd)
    #17 std::thread::_Impl<std::_Bind_simple<void (*(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>))(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, std::promise<int>)> >::_M_run() <null> (a.out+0x00000040a758)
    #18 <null> <null> (libstdc++.so.6+0x0000000b728f)

  Location is heap block of size 24 at 0x7d080000efa0 allocated by main thread:
    #0 operator new(unsigned long) <null> (libtsan.so.0+0x000000025733)
    #1 std::promise<int>::promise() <null> (a.out+0x000000404754)
    #2 main <null> (a.out+0x000000402413)

  Thread T1 (tid=29624, finished) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x000000026e74)
    #1 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>, void (*)()) <null> (libstdc++.so.6+0x0000000b73d2)
    #2 main <null> (a.out+0x000000402477)

SUMMARY: ThreadSanitizer: data race ??:0 std::future<int>::get()
==================
result=21
ThreadSanitizer: reported 2 warnings

@rettichschnidi
Copy link
Author

reto@debian-rs:~/sensorcon-ng$ clang++-3.6 -v --std=c++11 -fsanitize=thread -pthread tsan-false-positive.cpp && ./a.out
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.8.5
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/4.9.3
Found candidate GCC installation: /usr/bin/../lib/gcc/i586-linux-gnu/5.3.1
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8.5
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.8.5
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/i586-linux-gnu/5.3.1
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.8.5
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.3
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/5.3.1
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/usr/lib/llvm-3.6/bin/clang" -cc1 -triple x86_64-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name tsan-false-positive.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -target-linker-version 2.25.1 -v -dwarf-column-info -resource-dir /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/x86_64-linux-gnu/c++/5.3.1 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/x86_64-linux-gnu/c++/5.3.1 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include --std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/reto/sensorcon-ng -ferror-limit 19 -fmessage-length 210 -fsanitize=thread -pthread -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/tsan-false-positive-97ec23.o -x c++ tsan-false-positive.cpp
clang -cc1 version 3.6.2 based upon LLVM 3.6.2 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/x86_64-linux-gnu/c++/5.3.1"
#include "..." search starts here:
#include <...> search starts here:
 /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1
 /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/x86_64-linux-gnu/c++/5.3.1
 /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/backward
 /usr/local/include
 /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/include
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
 "/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/usr/lib/x86_64-linux-gnu/../../lib64 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../.. -L/usr/lib/llvm-3.6/bin/../lib -L/lib -L/usr/lib -whole-archive /usr/lib/llvm-3.6/bin/../lib/clang/3.6.2/lib/linux/libclang_rt.tsan-x86_64.a -no-whole-archive -export-dynamic /tmp/tsan-false-positive-97ec23.o -lstdc++ -lm --no-as-needed -lpthread -lrt -lm -ldl -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../x86_64-linux-gnu/crtn.o
result=21

@inetic
Copy link

inetic commented Oct 5, 2016

Hello Reto, I'm seeing this same message from g++'s thread sanitizer. Have you been able to confirm that this is a false positive? Or if it's not, a workaround?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment