I have programmed a boost::thread application, where I might have some race conditions based on valgrind/helgrind report. I want to identify the reason of these races.
The program is:
#include <boost/thread.hpp>
boost::mutex myMutex;
boost::condition_variable myConditionalVariable;
bool functionWasRun = false;
void function()
{
{
boost::lock_guard<boost::mutex> lock(myMutex);
functionWasRun = true;
}
myConditionalVariable.notify_one();
//doSomething1();
}
int main()
{
boost::thread pThread(function);
//Wait for the thread to start
boost::unique_lock<boost::mutex> lock(myMutex);
while (!functionWasRun)
myConditionalVariable.wait(lock);
//doSomething2();
pThread.join();
}
For this simple program valgrind/helgrind is reporting the following errors:
==10840== Helgrind, a thread error detector ==10840== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al. ==10840== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==10840== Command: ./boost_network_test ==10840== ==10840== ---Thread-Announcement------------------------------------------ ==10840== ==10840== Thread #1 is the program's root thread ==10840== ==10840== ---Thread-Announcement------------------------------------------ ==10840== ==10840== Thread #2 was created ==10840== at 0x6570EBE: clone (clone.S:74) ==10840== by 0x4E44199: do_clone.constprop.3 (createthread.c:75) ==10840== by 0x4E458BA: pthread_create@@GLIBC_2.2.5 (createthread.c:245) ==10840== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10840== by 0x547B3B8: boost::thread::start_thread_noexcept() (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.54.0) ==10840== by 0x53CFCC: boost::thread::start_thread() (thread.hpp:180) ==10840== by 0x53D31B: boost::thread::thread<void (&)()>(void (&)()) (thread.hpp:267) ==10840== by 0x53CA7B: main (main_test.cpp:20) ==10840== ==10840== ---------------------------------------------------------------- ==10840== ==10840== Possible data race during read of size 8 at 0x8A21E0 by thread #1 ==10840== Locks held: none ==10840== at 0x432CEB: boost::mutex::lock() (mutex.hpp:113) ==10840== by 0x43D197: boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:346) ==10840== by 0x43C1A0: boost::unique_lock<boost::mutex>::unique_lock(boost::mutex&) (lock_types.hpp:124) ==10840== by 0x53CA9E: main (main_test.cpp:23) ==10840== ==10840== This conflicts with a previous write of size 8 by thread #2 ==10840== Locks held: none ==10840== at 0x432CF6: boost::mutex::lock() (mutex.hpp:113) ==10840== by 0x43BFE9: boost::lock_guard<boost::mutex>::lock_guard(boost::mutex&) (lock_guard.hpp:38) ==10840== by 0x53C9DE: function() (main_test.cpp:10) ==10840== by 0x53DAAA: boost::detail::thread_data<void (*)()>::run() (thread.hpp:117) ==10840== by 0x547BA49: ??? (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.54.0) ==10840== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10840== by 0x4E45181: start_thread (pthread_create.c:312) ==10840== by 0x6570EFC: clone (clone.S:111) ==10840== ==10840== ---------------------------------------------------------------- ==10840== ==10840== Possible data race during write of size 8 at 0x8A21E0 by thread #1 ==10840== Locks held: none ==10840== at 0x432CF6: boost::mutex::lock() (mutex.hpp:113) ==10840== by 0x43D197: boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:346) ==10840== by 0x43C1A0: boost::unique_lock<boost::mutex>::unique_lock(boost::mutex&) (lock_types.hpp:124) ==10840== by 0x53CA9E: main (main_test.cpp:23) ==10840== ==10840== This conflicts with a previous write of size 8 by thread #2 ==10840== Locks held: none ==10840== at 0x432CF6: boost::mutex::lock() (mutex.hpp:113) ==10840== by 0x43BFE9: boost::lock_guard<boost::mutex>::lock_guard(boost::mutex&) (lock_guard.hpp:38) ==10840== by 0x53C9DE: function() (main_test.cpp:10) ==10840== by 0x53DAAA: boost::detail::thread_data<void (*)()>::run() (thread.hpp:117) ==10840== by 0x547BA49: ??? (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.54.0) ==10840== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==10840== by 0x4E45181: start_thread (pthread_create.c:312) ==10840== by 0x6570EFC: clone (clone.S:111) ==10840== ==10840== ==10840== For counts of detected and suppressed errors, rerun with: -v ==10840== Use --history-level=approx or =none to gain increased speed, at ==10840== the cost of reduced accuracy of conflicting-access information ==10840== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 15)
Please could you help me to identify how can I fix this program?
This program is run on Ubuntu 14.04LTS, x86_64, gcc ver. 4.8.2, libboost v.1.54, valgrind 3.10.0. My original program is a complex application using ActiveObject class which has been stripped down to a bare minimum to see the race condition pattern.
This thread may seem similar to Debug boost::thread application, high false positive rate but is involves a conditional variable/mutex.