std::thread helgrind

Discussion in 'C++' started by Garrett Hartshaw, Jan 2, 2011.

  1. Running helgrind (valgrind --tool=helgrind) gives a bunch of warnings
    about race conditions on the following code. Is it correct, and if so
    how do I fix it?

    -- The code
    #include <thread>

    class threads {
    public:
    void run() {
    std::thread thread( &threads::run_thread, this );
    thread.join();
    }

    private:
    void run_thread() {}
    };

    int main() {
    threads().run();
    }

    --the output from helgrind
    $ valgrind --tool=helgrind ./a.out
    ==15668== Helgrind, a thread error detector
    ==15668== Copyright (C) 2007-2009, and GNU GPL'd, by OpenWorks LLP et al.
    ==15668== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==15668== Command: ./a.out
    ==15668==
    ==15668== Thread #2 was created
    ==15668== at 0x58C612E: clone (clone.S:77)
    ==15668== by 0x55DDEDF: T.124 (createthread.c:75)
    ==15668== by 0x55DE3E1: pthread_create@@GLIBC_2.2.5 (createthread.c:256)
    ==15668== by 0x4C2B163: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668== by 0x4EEEB76:
    std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
    (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.2/libstdc++.so.6.0.13)
    ==15668== by 0x400F23: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668==
    ==15668== Thread #1 is the program's root thread
    ==15668==
    ==15668== Possible data race during write of size 8 at 0x7fefffbc0 by
    thread #2
    ==15668== at 0x4C2B2A3: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668== This conflicts with a previous read of size 8 by thread #1
    ==15668== at 0x4C2B178: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668== by 0x4EEEB76:
    std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
    (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.2/libstdc++.so.6.0.13)
    ==15668== by 0x400F23: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668==
    ==15668== Possible data race during read of size 8 at 0x7fefffbc0 by
    thread #1
    ==15668== at 0x4C2B18D: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668== by 0x4EEEB76:
    std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
    (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.2/libstdc++.so.6.0.13)
    ==15668== by 0x400F23: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== This conflicts with a previous write of size 8 by thread #2
    ==15668== at 0x4C2B2A3: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668==
    ==15668== Possible data race during write of size 8 at 0x7fefffbb8 by
    thread #1
    ==15668== at 0x400C31: __gnu_cxx::__exchange_and_add(int volatile*,
    int) (in /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400C9E: __gnu_cxx::__exchange_and_add_dispatch(int*,
    int) (in /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x40128E:
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4010A4:
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E83: std::__shared_ptr<std::thread::_Impl_base,
    (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E9D:
    std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400F2F: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== This conflicts with a previous read of size 8 by thread #2
    ==15668== at 0x4C2B24A: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668==
    ==15668== Possible data race during write of size 4 at 0x7fefffbb4 by
    thread #1
    ==15668== at 0x400C35: __gnu_cxx::__exchange_and_add(int volatile*,
    int) (in /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400C9E: __gnu_cxx::__exchange_and_add_dispatch(int*,
    int) (in /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x40128E:
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4010A4:
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E83: std::__shared_ptr<std::thread::_Impl_base,
    (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E9D:
    std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400F2F: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== This conflicts with a previous read of size 8 by thread #2
    ==15668== at 0x4C2B247: ??? (in
    /usr/lib64/valgrind/vgpreload_helgrind-amd64-linux.so)
    ==15668==
    ==15668== Possible data race during write of size 8 at 0x5b5a060 by
    thread #1
    ==15668== at 0x4021B0:
    std::thread::_Impl<std::_Bind<std::_Mem_fn<void (threads::*)()>
    ()(threads*)> >::~_Impl() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x402491:
    std::_Sp_destroy_inplace<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> >
    >::eek:perator()(std::thread::_Impl<std::_Bind<std::_Mem_fn<void

    (threads::*)()> ()(threads*)> >*) const (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x40223A:
    std::_Sp_counted_deleter<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> >*,
    std::_Sp_destroy_inplace<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> > >,
    std::allocator<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> > >,
    (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4012AF:
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4010A4:
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E83: std::__shared_ptr<std::thread::_Impl_base,
    (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E9D:
    std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400F2F: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400DE5: threads::run() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400CC7: main (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== This conflicts with a previous read of size 8 by thread #2
    ==15668== at 0x4EEEA26: ??? (in
    /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.2/libstdc++.so.6.0.13)
    ==15668==
    ==15668== Possible data race during read of size 8 at 0x5b5a070 by thread #1
    ==15668== at 0x40108E:
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E83: std::__shared_ptr<std::thread::_Impl_base,
    (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E9D:
    std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x401F0C: std::thread::_Impl_base::~_Impl_base() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4021C2:
    std::thread::_Impl<std::_Bind<std::_Mem_fn<void (threads::*)()>
    ()(threads*)> >::~_Impl() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x402491:
    std::_Sp_destroy_inplace<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> >
    >::eek:perator()(std::thread::_Impl<std::_Bind<std::_Mem_fn<void

    (threads::*)()> ()(threads*)> >*) const (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x40223A:
    std::_Sp_counted_deleter<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> >*,
    std::_Sp_destroy_inplace<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> > >,
    std::allocator<std::thread::_Impl<std::_Bind<std::_Mem_fn<void
    (threads::*)()> ()(threads*)> > >,
    (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4012AF:
    std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x4010A4:
    std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E83: std::__shared_ptr<std::thread::_Impl_base,
    (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400E9D:
    std::shared_ptr<std::thread::_Impl_base>::~shared_ptr() (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== by 0x400F2F: std::thread::thread<void (threads::*)(),
    threads* const>(void (threads::*&&)(), threads* const&&) (in
    /home/garrett/Programming/game/__rewrite_valgrind/a.out)
    ==15668== This conflicts with a previous write of size 8 by thread #2
    ==15668== at 0x4EEEA35: ??? (in
    /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.2/libstdc++.so.6.0.13)
    ==15668==
    ==15668==
    ==15668== For counts of detected and suppressed errors, rerun with: -v
    ==15668== Use --history-level=approx or =none to gain increased speed, at
    ==15668== the cost of reduced accuracy of conflicting-access information
    ==15668== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
    Garrett Hartshaw, Jan 2, 2011
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page