|
From: Dave O. <dav...@gm...> - 2014-06-09 06:51:31
|
[THERE ARE STILL PROBLEMS - SEE NEAR THE END OF THIS MESSAGE]
Hi,
Thank you for the updated instructions.
I tried again, like this:
<main.cc>
#include <valgrind/drd.h>
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(addr)
ANNOTATE_HAPPENS_BEFORE(addr)
#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(addr)
ANNOTATE_HAPPENS_AFTER(addr)
#include <iostream>
#include <thread>
int main()
{
std::thread t( []() { } );
t.join();
std::cerr << "Done." << std::endl;
return 0;
}
//
// From libstdc++-v3/src/c++11/thread.cc
//
extern "C" void* execute_native_thread_routine(void* __p)
{
std::thread::_Impl_base* __t = static_cast<std::thread::_Impl_base*>(__p);
std::thread::__shared_base_type __local;
__local.swap(__t->_M_this_ptr);
__try {
__t->_M_run();
} __catch(const __cxxabiv1::__forced_unwind&) {
__throw_exception_again;
} __catch(...) {
std::terminate();
}
return 0;
}
#include <system_error>
namespace std
{
void thread::_M_start_thread(__shared_base_type __b)
{
if (!__gthread_active_p())
#if __EXCEPTIONS
throw system_error(make_error_code(errc::operation_not_permitted),
"Enable multithreading to use std::thread");
#else
__throw_system_error(int(errc::operation_not_permitted));
#endif
__b->_M_this_ptr = __b;
int __e = __gthread_create(&_M_id._M_thread,
execute_native_thread_routine,
__b.get());
if (__e) {
__b->_M_this_ptr.reset();
__throw_system_error(__e);
}
}
}
</main.cc>
The false positives are now gone:
$ g++ -std=c++11 -Wall -Wextra -pthread main.cc
$ ./a.out
Done.
$ valgrind --tool=drd ./a.out
==13462== drd, a thread error detector
==13462== Copyright (C) 2006-2011, and GNU GPL'd, by Bart Van Assche.
==13462== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==13462== Command: ./a.out
==13462==
Done.
==13462==
==13462== For counts of detected and suppressed errors, rerun with: -v
==13462== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 12)
So far, so good.
If, however, I replace main() by the following bogus code:
<updated part of main.cc>
[other code as before]
int i = 0;
int main()
{
std::thread t1( []() { i = 1; } );
std::thread t2( []() { i = 2; } );
t1.join();
t2.join();
std::cerr << "i = " << i << std::endl;
return 0;
}
[other code as before]
</updated part of main.cc>
The problem now is that DRD does not warn about the data race:
$ g++ -std=c++11 -Wall -Wextra -pthread main.cc
$ ./a.out
i = 2
$ valgrind --tool=drd ./a.out
==14480== drd, a thread error detector
==14480== Copyright (C) 2006-2011, and GNU GPL'd, by Bart Van Assche.
==14480== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==14480== Command: ./a.out
==14480==
i = 2
==14480==
==14480== For counts of detected and suppressed errors, rerun with: -v
==14480== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 12)
My setup has not changed:
- RedHad Linux 2.6
- g++ 4.7.2
- Valgrind 3.7.0
-- dave
On Sat, Jun 7, 2014 at 4:50 PM, Bart Van Assche <bva...@ac...> wrote:
> On 06/06/14 09:33, Dave Ohlsson wrote:
> > However, the code you posted, and the included comments, match pretty
> > much what I already did.
>
> Hello Dave,
>
> I have updated the C++11 instructions in the DRD manual and also the
> drd/tests/std_thread.cpp test program. The DRD manual can be generated
> as follows:
>
> $ make -sC docs html-docs
> $ xdg-open docs/html/drd-manual.html
>
> Can you have a look ?
>
> Thanks,
>
> Bart.
>
|