|
From: Konstantin S. <kon...@gm...> - 2010-08-13 12:27:52
|
The annotations have been submitted to libstdc++ trunk and will appear in gcc 4.6. See also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45276 --kcc On Wed, Jul 14, 2010 at 4:21 PM, Konstantin Serebryany <kon...@gm...> wrote: > FYI: > I've constructed a test case which produces a false report with all > three tools. > The test case uses shared_ptr from the soon-to-become C++ standard > (I've built it with the fresh gcc trunk). > With the annotations which we are discussing with libstdc++ folks > these reports should be gone. > > --kcc > > % cat shared_ptr_test.cc > //#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(a) ANNOTATE_HAPPENS_BEFORE(a) > //#define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(a) ANNOTATE_HAPPENS_AFTER(a) > //#include "dynamic_annotations.h" > > #include <stdio.h> > #include <pthread.h> > #include <unistd.h> > #include <assert.h> > #include <memory> > using namespace std; > > class Foo { > public: > Foo() : a_(777) { } > ~Foo() { > a_ = 0xDEAD; > } > void Check() { > assert(a_ == 777); > } > private: > int a_; > }; > > shared_ptr<Foo> *s; > > pthread_mutex_t mu; > pthread_cond_t cv; > int done = 0; > > void *Thread(void*) { > shared_ptr<Foo> x(*s); > > pthread_mutex_lock(&mu); > done++; > pthread_cond_signal(&cv); > pthread_mutex_unlock(&mu); > > x->Check(); > // x is destructed > } > > const int kNThreads = 3; > > int main() { > s = new shared_ptr<Foo>(new Foo); > pthread_t t[kNThreads]; > pthread_mutex_init(&mu, 0); > pthread_cond_init(&cv, 0); > // start threads. > for (int i = 0; i < kNThreads; i++) { > pthread_create(&t[i], 0, Thread, 0); > } > // wait for threads to copy 's', but don't wait for threads to exit. > pthread_mutex_lock(&mu); > while (done != kNThreads) > pthread_cond_wait(&cv, &mu); > pthread_mutex_unlock(&mu); > delete s; > } > > > % g++ -g -std=c++0x -pthread shared_ptr_test.cc && echo > -----Helgrind---------; ~/valgrind/trunk/inst/bin/valgrind > --tool=helgrind ./a.out && echo --------------DRD----------- && > ~/valgrind/trunk/inst/bin/valgrind --tool=drd ./a.out > -----Helgrind--------- > ==7788== Helgrind, a thread error detector > ==7788== Copyright (C) 2007-2009, and GNU GPL'd, by OpenWorks LLP et al. > ==7788== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info > ==7788== Command: ./a.out > ==7788== > ==7788== Thread #1 is the program's root thread > ==7788== > ==7788== Thread #4 was created > ==7788== at 0x58E06BE: clone (clone.S:77) > ==7788== by 0x55E4172: pthread_create@@GLIBC_2.2.5 (createthread.c:75) > ==7788== by 0x4C2C210: pthread_create_WRK (hg_intercepts.c:241) > ==7788== by 0x4C2C2B9: pthread_create@* (hg_intercepts.c:268) > ==7788== by 0x400E28: main (shared_ptr_test.cc:52) > ==7788== > ==7788== Possible data race during write of size 4 at 0x5b7d040 by thread #1 > ==7788== at 0x400ECE: Foo::~Foo() (shared_ptr_test.cc:16) > ==7788== by 0x4013B7: std::_Sp_counted_ptr<Foo*, > (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in /tmp/z/a.out) > ==7788== by 0x401047: > std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() > (boost_sp_counted_base.h:146) > ==7788== by 0x400F8E: > std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() > (shared_ptr_base.h:353) > ==7788== by 0x400F25: std::__shared_ptr<Foo, > (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:553) > ==7788== by 0x400F3F: std::shared_ptr<Foo>::~shared_ptr() (shared_ptr.h:91) > ==7788== by 0x400E80: main (shared_ptr_test.cc:59) > ==7788== This conflicts with a previous read of size 4 by thread #4 > ==7788== at 0x400EE6: Foo::Check() (shared_ptr_test.cc:19) > ==7788== by 0x400D89: Thread(void*) (shared_ptr_test.cc:39) > ==7788== by 0x4C2C342: mythread_wrapper (hg_intercepts.c:213) > ==7788== by 0x55E39C9: start_thread (pthread_create.c:300) > ==7788== by 0x58E06FC: clone (clone.S:112) > ==7788== Address 0x5b7d040 is 0 bytes inside a block of size 4 alloc'd > ==7788== at 0x4C27ED5: operator new(unsigned long) (vg_replace_malloc.c:261) > ==7788== by 0x400DAC: main (shared_ptr_test.cc:46) > ==7788== > ==7788== > ==7788== For counts of detected and suppressed errors, rerun with: -v > ==7788== Use --history-level=approx or =none to gain increased speed, at > ==7788== the cost of reduced accuracy of conflicting-access information > ==7788== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 24 from 15) > --------------DRD----------- > ==7792== drd, a thread error detector > ==7792== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche. > ==7792== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info > ==7792== Command: ./a.out > ==7792== > ==7792== Conflicting store by thread 1 at 0x05b86030 size 4 > ==7792== at 0x400ECE: Foo::~Foo() (shared_ptr_test.cc:16) > ==7792== by 0x4013B7: std::_Sp_counted_ptr<Foo*, > (__gnu_cxx::_Lock_policy)2>::_M_dispose() (in /tmp/z/a.out) > ==7792== by 0x401047: > std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() > (boost_sp_counted_base.h:146) > ==7792== by 0x400F8E: > std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() > (shared_ptr_base.h:353) > ==7792== by 0x400F25: std::__shared_ptr<Foo, > (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:553) > ==7792== by 0x400F3F: std::shared_ptr<Foo>::~shared_ptr() (shared_ptr.h:91) > ==7792== by 0x400E80: main (shared_ptr_test.cc:59) > ==7792== Address 0x5b86030 is at offset 0 from 0x5b86030. Allocation context: > ==7792== at 0x4C29A05: operator new(unsigned long) (vg_replace_malloc.c:261) > ==7792== by 0x400DAC: main (shared_ptr_test.cc:46) > ==7792== Other segment start (thread 2) > ==7792== (thread finished, call stack no longer available) > ==7792== Other segment end (thread 2) > ==7792== (thread finished, call stack no longer available) > ==7792== Other segment start (thread 3) > ==7792== (thread finished, call stack no longer available) > ==7792== Other segment end (thread 3) > ==7792== (thread finished, call stack no longer available) > ==7792== Other segment start (thread 4) > ==7792== at 0x4C2BD19: pthread_mutex_unlock (drd_pthread_intercepts.c:633) > ==7792== by 0x400D75: Thread(void*) (shared_ptr_test.cc:37) > ==7792== by 0x4C344C4: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272) > ==7792== by 0x55EC9C9: start_thread (pthread_create.c:300) > ==7792== by 0x58E96FC: clone (clone.S:112) > ==7792== Other segment end (thread 4) > ==7792== at 0x58E5AE7: madvise (syscall-template.S:82) > ==7792== > ==7792== > ==7792== For counts of detected and suppressed errors, rerun with: -v > ==7792== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 16 from 15) > > > > > > > On Fri, Jul 9, 2010 at 3:48 PM, Konstantin Serebryany > <kon...@gm...> wrote: >> Sent a message to libstdc++ folks: >> http://gcc.gnu.org/ml/libstdc++/2010-07/msg00029.html >> >> --kcc >> >> On Thu, Jul 8, 2010 at 7:08 PM, Bart Van Assche <bva...@ac...> wrote: >>> On Thu, Jul 8, 2010 at 12:49 PM, Konstantin Serebryany >>> <kon...@gm...> wrote: >>>> I changed the code which I want to suggest to libstdc++: >>>> http://code.google.com/p/data-race-test/wiki/AtomicReferenceCounting#Proposal_to_libstdc++_developers >>>> This will allow to use any kind of annotations (including Intel >>>> Parallel Inspector's itt_notify_sync_releasing / >>>> itt_notify_sync_acquired). >>>> Please have another look. >>> >>> A few minor comments: in the text cited below, please add the word >>> "otherwise" at the beginning of the second line, replace "other" by >>> "else" and "reference counter" by "reference counters". >>> >>> // Do not use this function for anything other than decrementing >>> reference counter -- >>> // this will confuse race detectors and will make them more >>> conservative and slow. >>> >>> Bart. >>> >> > |