|
From: Jorge M. <jor...@gm...> - 2010-04-06 05:54:02
|
Dear all,
When I compile the following program with:
$ g++ -g -pthread threads.cpp
// begin program /////////////////////////////////////////////
// file: threads.cpp
#include <pthread.h>
#include <iostream>
#include <sstream>
void *threadEntry(void *threadid)
{
long tid;
tid = (long)threadid;
for (int i = 0; i<5; i++) {
std::stringstream myStream;
myStream << "this thread is " << tid;
std::string myString(myStream.str());
pthread_yield();
}
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[2];
int rc;
long t;
for(t=0; t<2; t++) {
rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
}
pthread_exit(NULL);
}
// end program /////////////////////////////////////////////
and run drd on it with:
$ valgrind --tool=drd ./a.out
I get the following output:
==16240== drd, a thread error detector
==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
copyright info
==16240== Command: ./a.out
==16240==
==16240== Thread 3:
==16240== Conflicting load by thread 3 at 0x05132e98 size 1
==16240== at 0x4ED44C8: std::ostream&
std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==16240== Other segment start (thread 2)
==16240== at 0x4C29F2F: pthread_mutex_unlock (drd_pthread_intercepts.c:633)
==16240== by 0x4EA387E: std::locale::locale() (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4ED7DEA: std::basic_stringstream<char,
std::char_traits<char>, std::allocator<char>
>::basic_stringstream(std::_Ios_Openmode) (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240== Other segment end (thread 2)
==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240==
==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
==16240== at 0x4ED44D3: std::ostream&
std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==16240== Other segment start (thread 2)
==16240== at 0x4C29F2F: pthread_mutex_unlock (drd_pthread_intercepts.c:633)
==16240== by 0x4EA387E: std::locale::locale() (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4ED7DEA: std::basic_stringstream<char,
std::char_traits<char>, std::allocator<char>
>::basic_stringstream(std::_Ios_Openmode) (in
/usr/lib/libstdc++.so.6.0.13)
==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240== Other segment end (thread 2)
==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
==16240== by 0x58DD80C: clone (clone.S:112)
==16240==
==16240==
==16240== For counts of detected and suppressed errors, rerun with: -v
==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from 140)
My question is: Are the errors reported real multi threading errors?
If not, how can I tell drd to suppress them? (In my real world program, I
have thousands of errors in hundreds of contexts, and I am trying to
find the real ones.)
If yes, can you help me understand what is wrong? Both threads only
use local variables. I have been reading about the global object
"locale" used by streams for localization, but I have read that it is
protected by a global mutex.
By the way, if in the program above I don't include iostream, then drd
reports almost a thousand errors from a hundred contexts!
Thank you very much!
Jorge Moraleda
FYI: I am running ubuntu linux 9.10. This is my system:
$ valgrind --version
valgrind-3.5.0-Debian
$ uname -r
2.6.31-20-generic
$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
4.4.1-4ubuntu9'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--enable-shared --enable-multiarch --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4
--program-suffix=-4.4 --enable-nls --enable-clocale=gnu
--enable-libstdcxx-debug --enable-objc-gc --disable-werror
--with-arch-32=i486 --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 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
|
|
From: Bart V. A. <bva...@ac...> - 2010-04-06 10:17:19
|
On Tue, Apr 6, 2010 at 7:53 AM, Jorge Moraleda <jor...@gm...> wrote:
>
> Dear all,
>
> When I compile the following program with:
> $ g++ -g -pthread threads.cpp
>
> // begin program /////////////////////////////////////////////
> // file: threads.cpp
> #include <pthread.h>
> #include <iostream>
> #include <sstream>
>
> void *threadEntry(void *threadid)
> {
> long tid;
> tid = (long)threadid;
> for (int i = 0; i<5; i++) {
> std::stringstream myStream;
> myStream << "this thread is " << tid;
> std::string myString(myStream.str());
> pthread_yield();
> }
> pthread_exit(NULL);
> }
>
> int main (int argc, char *argv[])
> {
> pthread_t threads[2];
> int rc;
> long t;
> for(t=0; t<2; t++) {
> rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
> }
> pthread_exit(NULL);
> }
> // end program /////////////////////////////////////////////
>
> and run drd on it with:
> $ valgrind --tool=drd ./a.out
>
> I get the following output:
>
> ==16240== drd, a thread error detector
> ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
> ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
> copyright info
> ==16240== Command: ./a.out
> ==16240==
> ==16240== Thread 3:
> ==16240== Conflicting load by thread 3 at 0x05132e98 size 1
> ==16240== at 0x4ED44C8: std::ostream&
> std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==16240== Other segment start (thread 2)
> ==16240== at 0x4C29F2F: pthread_mutex_unlock (drd_pthread_intercepts.c:633)
> ==16240== by 0x4EA387E: std::locale::locale() (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
> >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
> std::char_traits<char>, std::allocator<char>
> >::basic_stringstream(std::_Ios_Openmode) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240== Other segment end (thread 2)
> ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240==
> ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
> ==16240== at 0x4ED44D3: std::ostream&
> std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==16240== Other segment start (thread 2)
> ==16240== at 0x4C29F2F: pthread_mutex_unlock (drd_pthread_intercepts.c:633)
> ==16240== by 0x4EA387E: std::locale::locale() (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
> >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
> std::char_traits<char>, std::allocator<char>
> >::basic_stringstream(std::_Ios_Openmode) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240== Other segment end (thread 2)
> ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
> ==16240== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==16240== by 0x58DD80C: clone (clone.S:112)
> ==16240==
> ==16240==
> ==16240== For counts of detected and suppressed errors, rerun with: -v
> ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from 140)
>
> My question is: Are the errors reported real multi threading errors?
> If not, how can I tell drd to suppress them? (In my real world program, I
> have thousands of errors in hundreds of contexts, and I am trying to
> find the real ones.)
> If yes, can you help me understand what is wrong? Both threads only
> use local variables. I have been reading about the global object
> "locale" used by streams for localization, but I have read that it is
> protected by a global mutex.
Hello Jorge,
Unfortunately not all libraries have been designed with data-race
detection tools in mind. Several libraries contain code that triggers
benign data races. Examples are the I/O code in libstdc++ and in libc.
You can either create a suppression pattern to suppress the above
races, or even simpler, add the following code in main() before thread
creation starts:
std::ostringstream dummy;
dummy << 0;
The above code will make sure that locale initialization, which is
triggered by sending an number to an I/O stream, will happen before
any threads are created and hence no races will be reported anymore on
locale initialization.
Bart.
|
|
From: Konstantin S. <kon...@gm...> - 2010-04-06 10:26:23
|
On Tue, Apr 6, 2010 at 2:17 PM, Bart Van Assche <bva...@ac...> wrote:
> On Tue, Apr 6, 2010 at 7:53 AM, Jorge Moraleda <jor...@gm...>
> wrote:
> >
> > Dear all,
> >
> > When I compile the following program with:
> > $ g++ -g -pthread threads.cpp
> >
> > // begin program /////////////////////////////////////////////
> > // file: threads.cpp
> > #include <pthread.h>
> > #include <iostream>
> > #include <sstream>
> >
> > void *threadEntry(void *threadid)
> > {
> > long tid;
> > tid = (long)threadid;
> > for (int i = 0; i<5; i++) {
> > std::stringstream myStream;
> > myStream << "this thread is " << tid;
> > std::string myString(myStream.str());
> > pthread_yield();
> > }
> > pthread_exit(NULL);
> > }
> >
> > int main (int argc, char *argv[])
> > {
> > pthread_t threads[2];
> > int rc;
> > long t;
> > for(t=0; t<2; t++) {
> > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
> > }
> > pthread_exit(NULL);
> > }
> > // end program /////////////////////////////////////////////
> >
> > and run drd on it with:
> > $ valgrind --tool=drd ./a.out
> >
> > I get the following output:
> >
> > ==16240== drd, a thread error detector
> > ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
> > ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
> > copyright info
> > ==16240== Command: ./a.out
> > ==16240==
> > ==16240== Thread 3:
> > ==16240== Conflicting load by thread 3 at 0x05132e98 size 1
> > ==16240== at 0x4ED44C8: std::ostream&
> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==16240== Other segment start (thread 2)
> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
> (drd_pthread_intercepts.c:633)
> > ==16240== by 0x4EA387E: std::locale::locale() (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
> > std::char_traits<char>, std::allocator<char>
> > >::basic_stringstream(std::_Ios_Openmode) (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240== Other segment end (thread 2)
> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240==
> > ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
> > ==16240== at 0x4ED44D3: std::ostream&
> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==16240== Other segment start (thread 2)
> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
> (drd_pthread_intercepts.c:633)
> > ==16240== by 0x4EA387E: std::locale::locale() (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
> > std::char_traits<char>, std::allocator<char>
> > >::basic_stringstream(std::_Ios_Openmode) (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240== Other segment end (thread 2)
> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
> (drd_pthread_intercepts.c:272)
> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==16240== by 0x58DD80C: clone (clone.S:112)
> > ==16240==
> > ==16240==
> > ==16240== For counts of detected and suppressed errors, rerun with: -v
> > ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from
> 140)
> >
> > My question is: Are the errors reported real multi threading errors?
> > If not, how can I tell drd to suppress them? (In my real world program, I
> > have thousands of errors in hundreds of contexts, and I am trying to
> > find the real ones.)
> > If yes, can you help me understand what is wrong? Both threads only
> > use local variables. I have been reading about the global object
> > "locale" used by streams for localization, but I have read that it is
> > protected by a global mutex.
>
> Hello Jorge,
>
> Unfortunately not all libraries have been designed with data-race
> detection tools in mind. Several libraries contain code that triggers
> benign data races. Examples are the I/O code in libstdc++ and in libc.
>
> You can either create a suppression pattern to suppress the above
> races, or even simpler, add the following code in main() before thread
> creation starts:
>
> std::ostringstream dummy;
> dummy << 0;
>
> The above code will make sure that locale initialization, which is
> triggered by sending an number to an I/O stream, will happen before
> any threads are created and hence no races will be reported anymore on
> locale initialization.
>
This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE.
And suppressing errors in string guts may hide real races.
>
> Bart.
>
>
> ------------------------------------------------------------------------------
> Download Intel® Parallel Studio Eval
> Try the new software tools for yourself. Speed compiling, find bugs
> proactively, and fine-tune applications for parallel performance.
> See why Intel Parallel Studio got high marks during beta.
> http://p.sf.net/sfu/intel-sw-dev
> _______________________________________________
> Valgrind-users mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>
|
|
From: Bart V. A. <bva...@ac...> - 2010-04-06 10:30:35
|
On Tue, Apr 6, 2010 at 12:25 PM, Konstantin Serebryany
<kon...@gm...> wrote:
>
>
> On Tue, Apr 6, 2010 at 2:17 PM, Bart Van Assche <bva...@ac...> wrote:
>>
>> On Tue, Apr 6, 2010 at 7:53 AM, Jorge Moraleda <jor...@gm...>
>> wrote:
>> >
>> > Dear all,
>> >
>> > When I compile the following program with:
>> > $ g++ -g -pthread threads.cpp
>> >
>> > // begin program /////////////////////////////////////////////
>> > // file: threads.cpp
>> > #include <pthread.h>
>> > #include <iostream>
>> > #include <sstream>
>> >
>> > void *threadEntry(void *threadid)
>> > {
>> > long tid;
>> > tid = (long)threadid;
>> > for (int i = 0; i<5; i++) {
>> > std::stringstream myStream;
>> > myStream << "this thread is " << tid;
>> > std::string myString(myStream.str());
>> > pthread_yield();
>> > }
>> > pthread_exit(NULL);
>> > }
>> >
>> > int main (int argc, char *argv[])
>> > {
>> > pthread_t threads[2];
>> > int rc;
>> > long t;
>> > for(t=0; t<2; t++) {
>> > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
>> > }
>> > pthread_exit(NULL);
>> > }
>> > // end program /////////////////////////////////////////////
>> >
>> > and run drd on it with:
>> > $ valgrind --tool=drd ./a.out
>> >
>> > I get the following output:
>> >
>> > ==16240== drd, a thread error detector
>> > ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
>> > ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
>> > copyright info
>> > ==16240== Command: ./a.out
>> > ==16240==
>> > ==16240== Thread 3:
>> > ==16240== Conflicting load by thread 3 at 0x05132e98 size 1
>> > ==16240== at 0x4ED44C8: std::ostream&
>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240== Allocation context: BSS section of
>> > /usr/lib/libstdc++.so.6.0.13
>> > ==16240== Other segment start (thread 2)
>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
>> > (drd_pthread_intercepts.c:633)
>> > ==16240== by 0x4EA387E: std::locale::locale() (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
>> > std::char_traits<char>, std::allocator<char>
>> > >::basic_stringstream(std::_Ios_Openmode) (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240== Other segment end (thread 2)
>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240==
>> > ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
>> > ==16240== at 0x4ED44D3: std::ostream&
>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240== Allocation context: BSS section of
>> > /usr/lib/libstdc++.so.6.0.13
>> > ==16240== Other segment start (thread 2)
>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
>> > (drd_pthread_intercepts.c:633)
>> > ==16240== by 0x4EA387E: std::locale::locale() (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
>> > std::char_traits<char>, std::allocator<char>
>> > >::basic_stringstream(std::_Ios_Openmode) (in
>> > /usr/lib/libstdc++.so.6.0.13)
>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240== Other segment end (thread 2)
>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>> > (drd_pthread_intercepts.c:272)
>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>> > ==16240==
>> > ==16240==
>> > ==16240== For counts of detected and suppressed errors, rerun with: -v
>> > ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from
>> > 140)
>> >
>> > My question is: Are the errors reported real multi threading errors?
>> > If not, how can I tell drd to suppress them? (In my real world program,
>> > I
>> > have thousands of errors in hundreds of contexts, and I am trying to
>> > find the real ones.)
>> > If yes, can you help me understand what is wrong? Both threads only
>> > use local variables. I have been reading about the global object
>> > "locale" used by streams for localization, but I have read that it is
>> > protected by a global mutex.
>>
>> Hello Jorge,
>>
>> Unfortunately not all libraries have been designed with data-race
>> detection tools in mind. Several libraries contain code that triggers
>> benign data races. Examples are the I/O code in libstdc++ and in libc.
>>
>> You can either create a suppression pattern to suppress the above
>> races, or even simpler, add the following code in main() before thread
>> creation starts:
>>
>> std::ostringstream dummy;
>> dummy << 0;
>>
>> The above code will make sure that locale initialization, which is
>> triggered by sending an number to an I/O stream, will happen before
>> any threads are created and hence no races will be reported anymore on
>> locale initialization.
>
> This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE.
> And suppressing errors in string guts may hide real races.
The above indeed won't hide races on
_ZNSs4_Rep20_S_empty_rep_storageE. But I've never claimed that the
above code would hide these races. And Jorge didn't report any such
races in his original e-mail. So your reply seems off-topic to me.
Bart.
|
|
From: Jorge M. <jor...@gm...> - 2010-04-06 23:14:59
|
On Tue, Apr 6, 2010 at 3:30 AM, Bart Van Assche <bva...@ac...> wrote:
> On Tue, Apr 6, 2010 at 12:25 PM, Konstantin Serebryany
> <kon...@gm...> wrote:
>>
>>
>> On Tue, Apr 6, 2010 at 2:17 PM, Bart Van Assche <bva...@ac...> wrote:
>>>
>>> On Tue, Apr 6, 2010 at 7:53 AM, Jorge Moraleda <jor...@gm...>
>>> wrote:
>>> >
>>> > Dear all,
>>> >
>>> > When I compile the following program with:
>>> > $ g++ -g -pthread threads.cpp
>>> >
>>> > // begin program /////////////////////////////////////////////
>>> > // file: threads.cpp
>>> > #include <pthread.h>
>>> > #include <iostream>
>>> > #include <sstream>
>>> >
>>> > void *threadEntry(void *threadid)
>>> > {
>>> > long tid;
>>> > tid = (long)threadid;
>>> > for (int i = 0; i<5; i++) {
>>> > std::stringstream myStream;
>>> > myStream << "this thread is " << tid;
>>> > std::string myString(myStream.str());
>>> > pthread_yield();
>>> > }
>>> > pthread_exit(NULL);
>>> > }
>>> >
>>> > int main (int argc, char *argv[])
>>> > {
>>> > pthread_t threads[2];
>>> > int rc;
>>> > long t;
>>> > for(t=0; t<2; t++) {
>>> > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
>>> > }
>>> > pthread_exit(NULL);
>>> > }
>>> > // end program /////////////////////////////////////////////
>>> >
>>> > and run drd on it with:
>>> > $ valgrind --tool=drd ./a.out
>>> >
>>> > I get the following output:
>>> >
>>> > ==16240== drd, a thread error detector
>>> > ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
>>> > ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
>>> > copyright info
>>> > ==16240== Command: ./a.out
>>> > ==16240==
>>> > ==16240== Thread 3:
>>> > ==16240== Conflicting load by thread 3 at 0x05132e98 size 1
>>> > ==16240== at 0x4ED44C8: std::ostream&
>>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240== Allocation context: BSS section of
>>> > /usr/lib/libstdc++.so.6.0.13
>>> > ==16240== Other segment start (thread 2)
>>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
>>> > (drd_pthread_intercepts.c:633)
>>> > ==16240== by 0x4EA387E: std::locale::locale() (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
>>> > std::char_traits<char>, std::allocator<char>
>>> > >::basic_stringstream(std::_Ios_Openmode) (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240== Other segment end (thread 2)
>>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
>>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240==
>>> > ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
>>> > ==16240== at 0x4ED44D3: std::ostream&
>>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240== Allocation context: BSS section of
>>> > /usr/lib/libstdc++.so.6.0.13
>>> > ==16240== Other segment start (thread 2)
>>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock
>>> > (drd_pthread_intercepts.c:633)
>>> > ==16240== by 0x4EA387E: std::locale::locale() (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char>
>>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char,
>>> > std::char_traits<char>, std::allocator<char>
>>> > >::basic_stringstream(std::_Ios_Openmode) (in
>>> > /usr/lib/libstdc++.so.6.0.13)
>>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240== Other segment end (thread 2)
>>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
>>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14)
>>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper
>>> > (drd_pthread_intercepts.c:272)
>>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300)
>>> > ==16240== by 0x58DD80C: clone (clone.S:112)
>>> > ==16240==
>>> > ==16240==
>>> > ==16240== For counts of detected and suppressed errors, rerun with: -v
>>> > ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from
>>> > 140)
>>> >
>>> > My question is: Are the errors reported real multi threading errors?
>>> > If not, how can I tell drd to suppress them? (In my real world program,
>>> > I
>>> > have thousands of errors in hundreds of contexts, and I am trying to
>>> > find the real ones.)
>>> > If yes, can you help me understand what is wrong? Both threads only
>>> > use local variables. I have been reading about the global object
>>> > "locale" used by streams for localization, but I have read that it is
>>> > protected by a global mutex.
>>>
>>> Hello Jorge,
>>>
>>> Unfortunately not all libraries have been designed with data-race
>>> detection tools in mind. Several libraries contain code that triggers
>>> benign data races. Examples are the I/O code in libstdc++ and in libc.
>>>
>>> You can either create a suppression pattern to suppress the above
>>> races, or even simpler, add the following code in main() before thread
>>> creation starts:
>>>
>>> std::ostringstream dummy;
>>> dummy << 0;
>>>
>>> The above code will make sure that locale initialization, which is
>>> triggered by sending an number to an I/O stream, will happen before
>>> any threads are created and hence no races will be reported anymore on
>>> locale initialization.
>>
>> This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE.
>> And suppressing errors in string guts may hide real races.
>
> The above indeed won't hide races on
> _ZNSs4_Rep20_S_empty_rep_storageE. But I've never claimed that the
> above code would hide these races. And Jorge didn't report any such
> races in his original e-mail. So your reply seems off-topic to me.
>
> Bart.
>
Dear Bart and Konstantin,
Thank you very much for your comments. The trick of pre-initializing
the locale object solved a few of my errors, but I still have tons
related to strings and streams. This is another minimal test case:
#include <pthread.h>
#include <string>
#include <sstream>
void *threadEntry(void *threadid)
{
long tid;
tid = (long)threadid;
std::string myString;
for (int i = 0; i<5; i++) {
myString.clear();
pthread_yield();
}
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[2];
int rc;
long t;
std::ostringstream dummy;
dummy << 0;
for(t=0; t<2; t++) {
rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
}
pthread_exit(NULL);
}
==19065== drd, a thread error detector
==19065== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
==19065== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
copyright info
==19065== Command: ./a.out
==19065==
==19065== Thread 3:
==19065== Conflicting load by thread 3 at 0x05134160 size 8
==19065== at 0x4EDF1D7: std::string::clear() (in
/usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065== Conflicting load by thread 3 at 0x05134160 size 8
==19065== at 0x4EDE907: std::string::_M_mutate(unsigned long,
unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065== Conflicting load by thread 3 at 0x05134170 size 4
==19065== at 0x4EDE9B0: std::string::_M_mutate(unsigned long,
unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065== Conflicting store by thread 3 at 0x05134170 size 4
==19065== at 0x4EDE97D: std::string::_M_mutate(unsigned long,
unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065== Conflicting store by thread 3 at 0x05134160 size 8
==19065== at 0x4EDE984: std::string::_M_mutate(unsigned long,
unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065== Conflicting store by thread 3 at 0x05134178 size 1
==19065== at 0x4EDE987: std::string::_M_mutate(unsigned long,
unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
==19065== Other segment start (thread 2)
==19065== at 0x58DD7D1: clone (clone.S:84)
==19065== by 0x55E893F: ??? (allocatestack.c:743)
==19065== by 0x676D90F: ???
==19065== Other segment end (thread 2)
==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
==19065== by 0x58DD80C: clone (clone.S:112)
==19065==
==19065==
==19065== For counts of detected and suppressed errors, rerun with: -v
==19065== ERROR SUMMARY: 54 errors from 6 contexts (suppressed: 205 from 142)
Are all the race conditions in I/O code in libstdc++ bening?
If so, are there more things that I should initialize in my app before
I start creating threads and/or should I be looking into creating
suppression patterns for drd? Has anyone created them before? Why are
they not enabled by default in drd?
If not... What should I be reading,doing? Thank you in advance.
Jorge
|
|
From: Konstantin S. <kon...@gm...> - 2010-04-07 04:20:02
|
The race on _M_mutate is (most likely) the one discussed at http://permalink.gmane.org/gmane.comp.debugging.valgrind/10043 <http://permalink.gmane.org/gmane.comp.debugging.valgrind/10043>--kcc On Tue, Apr 6, 2010 at 4:14 PM, Jorge Moraleda <jor...@gm...>wrote: > On Tue, Apr 6, 2010 at 3:30 AM, Bart Van Assche <bva...@ac...> > wrote: > > On Tue, Apr 6, 2010 at 12:25 PM, Konstantin Serebryany > > <kon...@gm...> wrote: > >> > >> > >> On Tue, Apr 6, 2010 at 2:17 PM, Bart Van Assche <bva...@ac...> > wrote: > >>> > >>> On Tue, Apr 6, 2010 at 7:53 AM, Jorge Moraleda < > jor...@gm...> > >>> wrote: > >>> > > >>> > Dear all, > >>> > > >>> > When I compile the following program with: > >>> > $ g++ -g -pthread threads.cpp > >>> > > >>> > // begin program ///////////////////////////////////////////// > >>> > // file: threads.cpp > >>> > #include <pthread.h> > >>> > #include <iostream> > >>> > #include <sstream> > >>> > > >>> > void *threadEntry(void *threadid) > >>> > { > >>> > long tid; > >>> > tid = (long)threadid; > >>> > for (int i = 0; i<5; i++) { > >>> > std::stringstream myStream; > >>> > myStream << "this thread is " << tid; > >>> > std::string myString(myStream.str()); > >>> > pthread_yield(); > >>> > } > >>> > pthread_exit(NULL); > >>> > } > >>> > > >>> > int main (int argc, char *argv[]) > >>> > { > >>> > pthread_t threads[2]; > >>> > int rc; > >>> > long t; > >>> > for(t=0; t<2; t++) { > >>> > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t); > >>> > } > >>> > pthread_exit(NULL); > >>> > } > >>> > // end program ///////////////////////////////////////////// > >>> > > >>> > and run drd on it with: > >>> > $ valgrind --tool=drd ./a.out > >>> > > >>> > I get the following output: > >>> > > >>> > ==16240== drd, a thread error detector > >>> > ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche. > >>> > ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for > >>> > copyright info > >>> > ==16240== Command: ./a.out > >>> > ==16240== > >>> > ==16240== Thread 3: > >>> > ==16240== Conflicting load by thread 3 at 0x05132e98 size 1 > >>> > ==16240== at 0x4ED44C8: std::ostream& > >>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== Allocation context: BSS section of > >>> > /usr/lib/libstdc++.so.6.0.13 > >>> > ==16240== Other segment start (thread 2) > >>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock > >>> > (drd_pthread_intercepts.c:633) > >>> > ==16240== by 0x4EA387E: std::locale::locale() (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4EB4768: std::basic_ios<char, > std::char_traits<char> > >>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char, > >>> > std::char_traits<char>, std::allocator<char> > >>> > >::basic_stringstream(std::_Ios_Openmode) (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== Other segment end (thread 2) > >>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > >>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== > >>> > ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1 > >>> > ==16240== at 0x4ED44D3: std::ostream& > >>> > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== Allocation context: BSS section of > >>> > /usr/lib/libstdc++.so.6.0.13 > >>> > ==16240== Other segment start (thread 2) > >>> > ==16240== at 0x4C29F2F: pthread_mutex_unlock > >>> > (drd_pthread_intercepts.c:633) > >>> > ==16240== by 0x4EA387E: std::locale::locale() (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4EB4768: std::basic_ios<char, > std::char_traits<char> > >>> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x4ED7DEA: std::basic_stringstream<char, > >>> > std::char_traits<char>, std::allocator<char> > >>> > >::basic_stringstream(std::_Ios_Openmode) (in > >>> > /usr/lib/libstdc++.so.6.0.13) > >>> > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== Other segment end (thread 2) > >>> > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > >>> > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14) > >>> > ==16240== by 0x4C32870: vgDrd_thread_wrapper > >>> > (drd_pthread_intercepts.c:272) > >>> > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > >>> > ==16240== by 0x58DD80C: clone (clone.S:112) > >>> > ==16240== > >>> > ==16240== > >>> > ==16240== For counts of detected and suppressed errors, rerun with: > -v > >>> > ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 > from > >>> > 140) > >>> > > >>> > My question is: Are the errors reported real multi threading errors? > >>> > If not, how can I tell drd to suppress them? (In my real world > program, > >>> > I > >>> > have thousands of errors in hundreds of contexts, and I am trying to > >>> > find the real ones.) > >>> > If yes, can you help me understand what is wrong? Both threads only > >>> > use local variables. I have been reading about the global object > >>> > "locale" used by streams for localization, but I have read that it is > >>> > protected by a global mutex. > >>> > >>> Hello Jorge, > >>> > >>> Unfortunately not all libraries have been designed with data-race > >>> detection tools in mind. Several libraries contain code that triggers > >>> benign data races. Examples are the I/O code in libstdc++ and in libc. > >>> > >>> You can either create a suppression pattern to suppress the above > >>> races, or even simpler, add the following code in main() before thread > >>> creation starts: > >>> > >>> std::ostringstream dummy; > >>> dummy << 0; > >>> > >>> The above code will make sure that locale initialization, which is > >>> triggered by sending an number to an I/O stream, will happen before > >>> any threads are created and hence no races will be reported anymore on > >>> locale initialization. > >> > >> This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE. > >> And suppressing errors in string guts may hide real races. > > > > The above indeed won't hide races on > > _ZNSs4_Rep20_S_empty_rep_storageE. But I've never claimed that the > > above code would hide these races. And Jorge didn't report any such > > races in his original e-mail. So your reply seems off-topic to me. > > > > Bart. > > > > Dear Bart and Konstantin, > > Thank you very much for your comments. The trick of pre-initializing > the locale object solved a few of my errors, but I still have tons > related to strings and streams. This is another minimal test case: > > #include <pthread.h> > #include <string> > #include <sstream> > > void *threadEntry(void *threadid) > { > long tid; > tid = (long)threadid; > std::string myString; > for (int i = 0; i<5; i++) { > myString.clear(); > pthread_yield(); > } > pthread_exit(NULL); > } > > int main (int argc, char *argv[]) > { > pthread_t threads[2]; > int rc; > long t; > > std::ostringstream dummy; > dummy << 0; > for(t=0; t<2; t++) { > rc = pthread_create(&threads[t], NULL, threadEntry, (void > *)t); > } > pthread_exit(NULL); > } > > ==19065== drd, a thread error detector > ==19065== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche. > ==19065== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for > copyright info > ==19065== Command: ./a.out > ==19065== > ==19065== Thread 3: > ==19065== Conflicting load by thread 3 at 0x05134160 size 8 > ==19065== at 0x4EDF1D7: std::string::clear() (in > /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== Conflicting load by thread 3 at 0x05134160 size 8 > ==19065== at 0x4EDE907: std::string::_M_mutate(unsigned long, > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== Conflicting load by thread 3 at 0x05134170 size 4 > ==19065== at 0x4EDE9B0: std::string::_M_mutate(unsigned long, > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== Conflicting store by thread 3 at 0x05134170 size 4 > ==19065== at 0x4EDE97D: std::string::_M_mutate(unsigned long, > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== Conflicting store by thread 3 at 0x05134160 size 8 > ==19065== at 0x4EDE984: std::string::_M_mutate(unsigned long, > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== Conflicting store by thread 3 at 0x05134178 size 1 > ==19065== at 0x4EDE987: std::string::_M_mutate(unsigned long, > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13) > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==19065== Other segment start (thread 2) > ==19065== at 0x58DD7D1: clone (clone.S:84) > ==19065== by 0x55E893F: ??? (allocatestack.c:743) > ==19065== by 0x676D90F: ??? > ==19065== Other segment end (thread 2) > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13) > ==19065== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300) > ==19065== by 0x58DD80C: clone (clone.S:112) > ==19065== > ==19065== > ==19065== For counts of detected and suppressed errors, rerun with: -v > ==19065== ERROR SUMMARY: 54 errors from 6 contexts (suppressed: 205 from > 142) > > Are all the race conditions in I/O code in libstdc++ bening? > > If so, are there more things that I should initialize in my app before > I start creating threads and/or should I be looking into creating > suppression patterns for drd? Has anyone created them before? Why are > they not enabled by default in drd? > > If not... What should I be reading,doing? Thank you in advance. > > Jorge > |
|
From: Jorge M. <jor...@gm...> - 2010-04-07 01:38:33
|
>
> #include <pthread.h>
> #include <string>
> #include <sstream>
>
> void *threadEntry(void *threadid)
> {
> long tid;
> tid = (long)threadid;
> std::string myString;
> for (int i = 0; i<5; i++) {
> myString.clear();
> pthread_yield();
> }
> pthread_exit(NULL);
> }
>
> int main (int argc, char *argv[])
> {
> pthread_t threads[2];
> int rc;
> long t;
>
> std::ostringstream dummy;
> dummy << 0;
> for(t=0; t<2; t++) {
> rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
> }
> pthread_exit(NULL);
> }
>
> ==19065== drd, a thread error detector
> ==19065== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
> ==19065== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
> copyright info
> ==19065== Command: ./a.out
> ==19065==
> ==19065== Thread 3:
> ==19065== Conflicting load by thread 3 at 0x05134160 size 8
> ==19065== at 0x4EDF1D7: std::string::clear() (in
> /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065== Conflicting load by thread 3 at 0x05134160 size 8
> ==19065== at 0x4EDE907: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065== Conflicting load by thread 3 at 0x05134170 size 4
> ==19065== at 0x4EDE9B0: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065== Conflicting store by thread 3 at 0x05134170 size 4
> ==19065== at 0x4EDE97D: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065== Conflicting store by thread 3 at 0x05134160 size 8
> ==19065== at 0x4EDE984: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065== Conflicting store by thread 3 at 0x05134178 size 1
> ==19065== at 0x4EDE987: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==19065== Other segment start (thread 2)
> ==19065== at 0x58DD7D1: clone (clone.S:84)
> ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> ==19065== by 0x676D90F: ???
> ==19065== Other segment end (thread 2)
> ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> ==19065== by 0x58DD80C: clone (clone.S:112)
> ==19065==
> ==19065==
> ==19065== For counts of detected and suppressed errors, rerun with: -v
> ==19065== ERROR SUMMARY: 54 errors from 6 contexts (suppressed: 205 from 142)
>
> Are all the race conditions in I/O code in libstdc++ bening?
>
> If so, are there more things that I should initialize in my app before
> I start creating threads and/or should I be looking into creating
> suppression patterns for drd? Has anyone created them before? Why are
> they not enabled by default in drd?
>
> If not... What should I be reading,doing? Thank you in advance.
>
> Jorge
>
I found the following bug-report against gcc:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518
It seems that the problem is fixed in gcc 4.5. Until it is released, I
added code to my application to not clear empty strings, and it seems
to solve all the these problems. Thank you very much.
Jorge
|
|
From: Bart V. A. <bva...@ac...> - 2010-04-07 17:51:32
|
On Wed, Apr 7, 2010 at 3:32 AM, Jorge Moraleda <jor...@gm...> wrote:
>
> >
> > #include <pthread.h>
> > #include <string>
> > #include <sstream>
> >
> > void *threadEntry(void *threadid)
> > {
> > long tid;
> > tid = (long)threadid;
> > std::string myString;
> > for (int i = 0; i<5; i++) {
> > myString.clear();
> > pthread_yield();
> > }
> > pthread_exit(NULL);
> > }
> >
> > int main (int argc, char *argv[])
> > {
> > pthread_t threads[2];
> > int rc;
> > long t;
> >
> > std::ostringstream dummy;
> > dummy << 0;
> > for(t=0; t<2; t++) {
> > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t);
> > }
> > pthread_exit(NULL);
> > }
> >
> > ==19065== drd, a thread error detector
> > ==19065== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
> > ==19065== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
> > copyright info
> > ==19065== Command: ./a.out
> > ==19065==
> > ==19065== Thread 3:
> > ==19065== Conflicting load by thread 3 at 0x05134160 size 8
> > ==19065== at 0x4EDF1D7: std::string::clear() (in
> > /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065== Conflicting load by thread 3 at 0x05134160 size 8
> > ==19065== at 0x4EDE907: std::string::_M_mutate(unsigned long,
> > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065== Conflicting load by thread 3 at 0x05134170 size 4
> > ==19065== at 0x4EDE9B0: std::string::_M_mutate(unsigned long,
> > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065== Conflicting store by thread 3 at 0x05134170 size 4
> > ==19065== at 0x4EDE97D: std::string::_M_mutate(unsigned long,
> > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065== Conflicting store by thread 3 at 0x05134160 size 8
> > ==19065== at 0x4EDE984: std::string::_M_mutate(unsigned long,
> > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065== Conflicting store by thread 3 at 0x05134178 size 1
> > ==19065== at 0x4EDE987: std::string::_M_mutate(unsigned long,
> > unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> > ==19065== by 0x400A5B: threadEntry(void*) (threads.cpp:12)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> > ==19065== Other segment start (thread 2)
> > ==19065== at 0x58DD7D1: clone (clone.S:84)
> > ==19065== by 0x55E893F: ??? (allocatestack.c:743)
> > ==19065== by 0x676D90F: ???
> > ==19065== Other segment end (thread 2)
> > ==19065== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so)
> > ==19065== by 0x400A60: threadEntry(void*) (threads.cpp:13)
> > ==19065== by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> > ==19065== by 0x55E8A03: start_thread (pthread_create.c:300)
> > ==19065== by 0x58DD80C: clone (clone.S:112)
> > ==19065==
> > ==19065==
> > ==19065== For counts of detected and suppressed errors, rerun with: -v
> > ==19065== ERROR SUMMARY: 54 errors from 6 contexts (suppressed: 205 from 142)
> >
> > Are all the race conditions in I/O code in libstdc++ bening?
They should -- each race in libstdc++ that is not benign is a bug.
> > If so, are there more things that I should initialize in my app before
> > I start creating threads and/or should I be looking into creating
> > suppression patterns for drd? Has anyone created them before? Why are
> > they not enabled by default in drd?
> >
> > If not... What should I be reading,doing? Thank you in advance.
>
> I found the following bug-report against gcc:
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518
> It seems that the problem is fixed in gcc 4.5. Until it is released, I
> added code to my application to not clear empty strings, and it seems
> to solve all the these problems. Thank you very much.
Thanks for the gcc bugzilla link -- that bug report is interesting.
Since the races on _S_empty_rep_storage are false positives, it is
safe to suppress these races. You can suppress these races using the
following dirty hack:
* add #include "drd/drd.h" in the same source file that contains the
main() function.
* add the following code near the beginning of the main() function:
extern char _ZNSs4_Rep20_S_empty_rep_storageE[32];
DRD_IGNORE_VAR(_ZNSs4_Rep20_S_empty_rep_storageE);
The above two statements tell DRD to ignore all load and store
operations in the 32-byte address range starting at
&std::basic_string<char, std::char_traits<char>, std::allocator<char>
>::_Rep::_S_empty_rep_storage.
Note: from Valgrind 3.6.0 on DRD will support the
ANNOTATE_BENIGN_RACE_SIZED() macro. This macro does the same as
DRD_IGNORE_VAR() but has an explicit size argument.
Bart.
|
|
From: Jorge M. <jor...@gm...> - 2010-04-08 02:25:03
|
> > > > I found the following bug-report against gcc: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40518 > > It seems that the problem is fixed in gcc 4.5. Until it is released, I > > added code to my application to not clear empty strings, and it seems > > to solve all the these problems. Thank you very much. > > Thanks for the gcc bugzilla link -- that bug report is interesting. > Since the races on _S_empty_rep_storage are false positives, it is > safe to suppress these races. You can suppress these races using the > following dirty hack: > * add #include "drd/drd.h" in the same source file that contains the > main() function. > * add the following code near the beginning of the main() function: > > extern char _ZNSs4_Rep20_S_empty_rep_storageE[32]; > DRD_IGNORE_VAR(_ZNSs4_Rep20_S_empty_rep_storageE); > > The above two statements tell DRD to ignore all load and store > operations in the 32-byte address range starting at > &std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_Rep::_S_empty_rep_storage. > > Note: from Valgrind 3.6.0 on DRD will support the > ANNOTATE_BENIGN_RACE_SIZED() macro. This macro does the same as > DRD_IGNORE_VAR() but has an explicit size argument. > > Bart. > Thank you. The "dirty trick" was very handy! I am no longer getting any strange race condition reports. Regards, Jorge |
|
From: Jorge M. <jor...@gm...> - 2010-04-21 01:40:47
|
>> Hello Jorge, >> >> Unfortunately not all libraries have been designed with data-race >> detection tools in mind. Several libraries contain code that triggers >> benign data races. Examples are the I/O code in libstdc++ and in libc. >> >> You can either create a suppression pattern to suppress the above >> races, or even simpler, add the following code in main() before thread >> creation starts: >> >> std::ostringstream dummy; >> dummy << 0; >> >> The above code will make sure that locale initialization, which is >> triggered by sending an number to an I/O stream, will happen before >> any threads are created and hence no races will be reported anymore on >> locale initialization. > > This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE. > And suppressing errors in string guts may hide real races. >> >> Bart. >> Hello Konstanting and Bart and others, I get race condition warnings ==20312== at 0x4C29303: pthread_mutex_lock (drd_pthread_intercepts.c:580) ==20312== by 0x6EAC85E: std::locale::locale() (in /usr/lib/libstdc++.so.6.0.13) ==20312== by 0x6EE0C93: std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::_Ios_Openmode) (in /usr/lib/libstdc++.so.6.0.13) when constructing std::stringstream and std::istringstream's. These look similar to the ones I asked about for std::ostringstream a few weeks ago. I tried a similar trick to the one Konstantin suggested for ostringstream. Namely, to write the following lines before thread creation starts: std::stringstream dummy2; dummy2 << 0; std::istringstream dummy3(dummy2.str()); But I still get warnings. Is there any initialization trick that works? Has a bug report been already filed against the stl? That is, assuming these are real bugs, I have not been able to find any information about locale race conditions on the web. If they are not real bugs, but false positives, are there any "magic" drd macros, like the one Konstantin described for the string::clear method extern char _ZNSs4_Rep20_S_empty_rep_storageE[32]; DRD_IGNORE_VAR(_ZNSs4_Rep20_S_empty_rep_storageE); that I can include to not report these errors? By the way, I also get these race condition warnings for locale initialization when using boost::lexical_cast. Thank you! Jorge |
|
From: Konstantin S. <kon...@gm...> - 2010-04-21 02:40:48
|
On Wed, Apr 21, 2010 at 5:40 AM, Jorge Moraleda <jor...@gm...>wrote: > >> Hello Jorge, > >> > >> Unfortunately not all libraries have been designed with data-race > >> detection tools in mind. Several libraries contain code that triggers > >> benign data races. Examples are the I/O code in libstdc++ and in libc. > >> > >> You can either create a suppression pattern to suppress the above > >> races, or even simpler, add the following code in main() before thread > >> creation starts: > >> > >> std::ostringstream dummy; > >> dummy << 0; > >> > >> The above code will make sure that locale initialization, which is > >> triggered by sending an number to an I/O stream, will happen before > >> any threads are created and hence no races will be reported anymore on > >> locale initialization. > > > > This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE. > > And suppressing errors in string guts may hide real races. > >> > >> Bart. > >> > > Hello Konstanting and Bart and others, > > I get race condition warnings > > ==20312== at 0x4C29303: pthread_mutex_lock > (drd_pthread_intercepts.c:580) > this looks different. Please also send the full reports next time. Did you try Helgrind and/or ThreadSanitizer? --kcc > ==20312== by 0x6EAC85E: std::locale::locale() (in > /usr/lib/libstdc++.so.6.0.13) > ==20312== by 0x6EE0C93: std::basic_stringstream<char, > std::char_traits<char>, std::allocator<char> > >::basic_stringstream(std::_Ios_Openmode) (in > /usr/lib/libstdc++.so.6.0.13) > > when constructing std::stringstream and std::istringstream's. These > look similar to the ones I asked about for std::ostringstream a few > weeks ago. I tried a similar trick to the one Konstantin suggested for > ostringstream. Namely, to write the following lines before thread > creation starts: > > std::stringstream dummy2; > dummy2 << 0; > std::istringstream dummy3(dummy2.str()); > > But I still get warnings. Is there any initialization trick that > works? Has a bug report been already filed against the stl? That is, > assuming these are real bugs, I have not been able to find any > information about locale race conditions on the web. If they are not > real bugs, but false positives, are there any "magic" drd macros, like > the one Konstantin described for the string::clear method > > extern char _ZNSs4_Rep20_S_empty_rep_storageE[32]; > DRD_IGNORE_VAR(_ZNSs4_Rep20_S_empty_rep_storageE); > > that I can include to not report these errors? > > By the way, I also get these race condition warnings for locale > initialization when using boost::lexical_cast. > > Thank you! > > Jorge > |
|
From: Bart V. A. <bva...@ac...> - 2010-05-08 11:30:17
|
On Wed, Apr 21, 2010 at 3:40 AM, Jorge Moraleda <jor...@gm...> wrote: >>> Hello Jorge, >>> >>> Unfortunately not all libraries have been designed with data-race >>> detection tools in mind. Several libraries contain code that triggers >>> benign data races. Examples are the I/O code in libstdc++ and in libc. >>> >>> You can either create a suppression pattern to suppress the above >>> races, or even simpler, add the following code in main() before thread >>> creation starts: >>> >>> std::ostringstream dummy; >>> dummy << 0; >>> >>> The above code will make sure that locale initialization, which is >>> triggered by sending an number to an I/O stream, will happen before >>> any threads are created and hence no races will be reported anymore on >>> locale initialization. >> >> This will not hide the race on _ZNSs4_Rep20_S_empty_rep_storageE. >> And suppressing errors in string guts may hide real races. >>> >>> Bart. >>> > > Hello Konstanting and Bart and others, > > I get race condition warnings > > ==20312== at 0x4C29303: pthread_mutex_lock (drd_pthread_intercepts.c:580) > ==20312== by 0x6EAC85E: std::locale::locale() (in > /usr/lib/libstdc++.so.6.0.13) > ==20312== by 0x6EE0C93: std::basic_stringstream<char, > std::char_traits<char>, std::allocator<char> >>::basic_stringstream(std::_Ios_Openmode) (in > /usr/lib/libstdc++.so.6.0.13) > > when constructing std::stringstream and std::istringstream's. These > look similar to the ones I asked about for std::ostringstream a few > weeks ago. I tried a similar trick to the one Konstantin suggested for > ostringstream. Namely, to write the following lines before thread > creation starts: > > std::stringstream dummy2; > dummy2 << 0; > std::istringstream dummy3(dummy2.str()); > > But I still get warnings. Is there any initialization trick that > works? Has a bug report been already filed against the stl? That is, > assuming these are real bugs, I have not been able to find any > information about locale race conditions on the web. If they are not > real bugs, but false positives, are there any "magic" drd macros, like > the one Konstantin described for the string::clear method > > extern char _ZNSs4_Rep20_S_empty_rep_storageE[32]; > DRD_IGNORE_VAR(_ZNSs4_Rep20_S_empty_rep_storageE); > > that I can include to not report these errors? > > By the way, I also get these race condition warnings for locale > initialization when using boost::lexical_cast. Have you already found a workaround that allows to avoid triggering the race report on std::locale::locale() ? If not, it would help if you could post a small example that allows to reproduce this behavior. Bart. |
|
From: Konstantin S. <kon...@gm...> - 2010-05-11 09:20:37
|
> > > Have you already found a workaround that allows to avoid triggering > the race report on std::locale::locale() ? If not, it would help if > you could post a small example that allows to reproduce this behavior. > You may like the test NegativeTests.EmptyRepTest from http://code.google.com/p/data-race-test/wiki/RacecheckUnittest % ~/valgrind/trunk/inst/bin/valgrind --tool=helgrind ./bin/racecheck_unittest-linux-x86-O0 --gtest_filter="NegativeTests.EmptyRepTest" ==28925== Possible data race during read of size 4 at 0x7fbf5b8 by thread #3 ==28925== at 0x7F6F3A2: std::string::erase(unsigned int, unsigned int) (in /usr/grte/v1/lib/libstdc++.so.6.0.9) ==28925== by 0x804CB82: NegativeTests_EmptyRep::Worker() (racecheck_unittest.cc:3168) ==28925== by 0x806E806: MyThread::ThreadBody(MyThread*) (thread_wrappers_pthread.h:329) ==28925== by 0x47C4155: mythread_wrapper (hg_intercepts.c:213) ==28925== by 0x47F1024: start_thread (in /usr/grte/v1/lib/ libpthread-2.3.6.so) ==28925== by 0x1BD4A75D: clone (in /usr/grte/v1/lib/libc-2.3.6.so) ==28925== This conflicts with a previous write of size 4 by thread #2 ==28925== at 0x7F6EC1B: std::string::_M_mutate(unsigned int, unsigned int, unsigned int) (in /usr/grte/v1/lib/libstdc++.so.6.0.9) ==28925== by 0x7F6F3C6: std::string::erase(unsigned int, unsigned int) (in /usr/grte/v1/lib/libstdc++.so.6.0.9) ==28925== by 0x804CB82: NegativeTests_EmptyRep::Worker() (racecheck_unittest.cc:3168) ==28925== by 0x806E806: MyThread::ThreadBody(MyThread*) (thread_wrappers_pthread.h:329) ==28925== by 0x47C4155: mythread_wrapper (hg_intercepts.c:213) ==28925== by 0x47F1024: start_thread (in /usr/grte/v1/lib/ libpthread-2.3.6.so) ==28925== by 0x1BD4A75D: clone (in /usr/grte/v1/lib/libc-2.3.6.so) % ~/valgrind/trunk/inst/bin/valgrind --tool=drd ./bin/racecheck_unittest-linux-x86-O0 --gtest_filter="NegativeTests.EmptyRepTest" ==28930== ==28930== Conflicting load by thread 3 at 0x04b1f5b8 size 4 ==28930== at 0x4ACEB7E: std::string::_M_mutate(unsigned int, unsigned int, unsigned int) (in /usr/grte/v1/lib/libstdc++.so.6.0.9) ==28930== by 0x4ACF3C6: std::string::erase(unsigned int, unsigned int) (in /usr/grte/v1/lib/libstdc++.so.6.0.9) ==28930== by 0x804CB82: NegativeTests_EmptyRep::Worker() (racecheck_unittest.cc:3168) ==28930== by 0x806E806: MyThread::ThreadBody(MyThread*) (thread_wrappers_pthread.h:329) ==28930== by 0x47C9BBD: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272) ==28930== by 0x47F7024: start_thread (in /usr/grte/v1/lib/ libpthread-2.3.6.so) ==28930== by 0x4BED75D: clone (in /usr/grte/v1/lib/libc-2.3.6.so) ==28930== Allocation context: BSS section of /usr/grte/v1/lib/libstdc++.so.6.0.9 ==28930== Other segment start (thread 2) ==28930== (thread finished, call stack no longer available) ==28930== Other segment end (thread 2) ==28930== (thread finished, call stack no longer available) ==28930== --kcc |
|
From: Konstantin S. <kon...@gm...> - 2010-04-06 06:57:40
|
This could be the same issue as discussed in http://permalink.gmane.org/gmane.comp.debugging.valgrind/10043 <http://permalink.gmane.org/gmane.comp.debugging.valgrind/10043>--kcc On Tue, Apr 6, 2010 at 9:53 AM, Jorge Moraleda <jor...@gm...>wrote: > Dear all, > > When I compile the following program with: > $ g++ -g -pthread threads.cpp > > // begin program ///////////////////////////////////////////// > // file: threads.cpp > #include <pthread.h> > #include <iostream> > #include <sstream> > > void *threadEntry(void *threadid) > { > long tid; > tid = (long)threadid; > for (int i = 0; i<5; i++) { > std::stringstream myStream; > myStream << "this thread is " << tid; > std::string myString(myStream.str()); > pthread_yield(); > } > pthread_exit(NULL); > } > > int main (int argc, char *argv[]) > { > pthread_t threads[2]; > int rc; > long t; > for(t=0; t<2; t++) { > rc = pthread_create(&threads[t], NULL, threadEntry, (void *)t); > } > pthread_exit(NULL); > } > // end program ///////////////////////////////////////////// > > and run drd on it with: > $ valgrind --tool=drd ./a.out > > I get the following output: > > ==16240== drd, a thread error detector > ==16240== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche. > ==16240== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for > copyright info > ==16240== Command: ./a.out > ==16240== > ==16240== Thread 3: > ==16240== Conflicting load by thread 3 at 0x05132e98 size 1 > ==16240== at 0x4ED44C8: std::ostream& > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==16240== Other segment start (thread 2) > ==16240== at 0x4C29F2F: pthread_mutex_unlock > (drd_pthread_intercepts.c:633) > ==16240== by 0x4EA387E: std::locale::locale() (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4ED7DEA: std::basic_stringstream<char, > std::char_traits<char>, std::allocator<char> > >::basic_stringstream(std::_Ios_Openmode) (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== Other segment end (thread 2) > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== > ==16240== Conflicting load by thread 3 at 0x05132eb9 size 1 > ==16240== at 0x4ED44D3: std::ostream& > std::ostream::_M_insert<long>(long) (in /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x400C48: threadEntry(void*) (threads.cpp:12) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13 > ==16240== Other segment start (thread 2) > ==16240== at 0x4C29F2F: pthread_mutex_unlock > (drd_pthread_intercepts.c:633) > ==16240== by 0x4EA387E: std::locale::locale() (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4E9FE5F: std::ios_base::_M_init() (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4EB4768: std::basic_ios<char, std::char_traits<char> > >::init(std::basic_streambuf<char, std::char_traits<char> >*) (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x4ED7DEA: std::basic_stringstream<char, > std::char_traits<char>, std::allocator<char> > >::basic_stringstream(std::_Ios_Openmode) (in > /usr/lib/libstdc++.so.6.0.13) > ==16240== by 0x400C21: threadEntry(void*) (threads.cpp:11) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== Other segment end (thread 2) > ==16240== at 0x58ACEB7: sched_yield (in /lib/libc-2.10.1.so) > ==16240== by 0x400C63: threadEntry(void*) (threads.cpp:14) > ==16240== by 0x4C32870: vgDrd_thread_wrapper > (drd_pthread_intercepts.c:272) > ==16240== by 0x55E8A03: start_thread (pthread_create.c:300) > ==16240== by 0x58DD80C: clone (clone.S:112) > ==16240== > ==16240== > ==16240== For counts of detected and suppressed errors, rerun with: -v > ==16240== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 208 from > 140) > > My question is: Are the errors reported real multi threading errors? > If not, how can I tell drd to suppress them? (In my real world program, I > have thousands of errors in hundreds of contexts, and I am trying to > find the real ones.) > If yes, can you help me understand what is wrong? Both threads only > use local variables. I have been reading about the global object > "locale" used by streams for localization, but I have read that it is > protected by a global mutex. > > By the way, if in the program above I don't include iostream, then drd > reports almost a thousand errors from a hundred contexts! > > Thank you very much! > > Jorge Moraleda > > FYI: I am running ubuntu linux 9.10. This is my system: > > $ valgrind --version > valgrind-3.5.0-Debian > > $ uname -r > 2.6.31-20-generic > > $ gcc -v > Using built-in specs. > Target: x86_64-linux-gnu > Configured with: ../src/configure -v --with-pkgversion='Ubuntu > 4.4.1-4ubuntu9' > --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs > --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr > --enable-shared --enable-multiarch --enable-linker-build-id > --with-system-zlib --libexecdir=/usr/lib --without-included-gettext > --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 > --program-suffix=-4.4 --enable-nls --enable-clocale=gnu > --enable-libstdcxx-debug --enable-objc-gc --disable-werror > --with-arch-32=i486 --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 4.4.1 (Ubuntu 4.4.1-4ubuntu9) > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > |