Tuesday, April 6, 2010

valgrind and iostream/locale

$ valgrind --tool=drd ./a.out

==16240== Conflicting load by thread 3 at 0x05132eb9 size 1
==16240== at 0x4ED44D3: std::ostream& std::ostream::_M_insert(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 >::init(std::basic_streambuf<char, std::char_traits >*) (in /usr/lib/libstdc++.so.6.0.13)
==16240== by 0x4ED7DEA: std::basic_stringstream<char, std::char_traits, std::allocator >::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)
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.

No comments: