2010/5/27 Jorge Moraleda <[email protected]>:
> Dear all,
>
> Am I doing something wrong, or is is there a race condition somewhere
> in std::istringstream and/or std::getline?
>
> (Bart, Konstantin, this ended up being the error that I've been trying
> to track down for a while and that I thought --erroneously-- was
> caused by std::locale)
>
> This program:
>
> /// file: thread.cpp
> #include <pthread.h>
> #include <string>
> #include <sstream>
>
> void *threadEntry(void *threadid)
> {
>
>         std::string bar("01\n23");
>         std::istringstream content(bar);
>
>                std::string line;
>                std::getline(content,line);
>
>    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);
> }
>
> when compiled using g++ -g -pthread thread.cpp
> and run with valgrind --tool=drd ./a.out
>
> produces the following output:
>
> ==10635== drd, a thread error detector
> ==10635== Copyright (C) 2006-2009, and GNU GPL'd, by Bart Van Assche.
> ==10635== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for
> copyright info
> ==10635== Command: ./a.out
> ==10635==
> ==10635== Thread 3:
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EBBC2A: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDE907: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBC32: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134170 size 4
> ==10635==    at 0x4EDE9B0: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBC32: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting store by thread 3 at 0x05134170 size 4
> ==10635==    at 0x4EDE97D: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBC32: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting store by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDE984: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBC32: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting store by thread 3 at 0x05134178 size 1
> ==10635==    at 0x4EDE987: std::string::_M_mutate(unsigned long,
> unsigned long, unsigned long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBC32: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDE3F5: std::string::append(char const*, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBCF1: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDE1CE: std::string::reserve(unsigned long) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EDE437: std::string::append(char const*, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBCF1: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDD6A9:
> std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EDE1EB: std::string::reserve(unsigned long) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EDE437: std::string::append(char const*, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBCF1: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635== Conflicting load by thread 3 at 0x05134160 size 8
> ==10635==    at 0x4EDD6BB:
> std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EDE1EB: std::string::reserve(unsigned long) (in
> /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EDE437: std::string::append(char const*, unsigned
> long) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x4EBBCF1: std::basic_istream<char,
> std::char_traits<char> >& std::getline<char, std::char_traits<char>,
> std::allocator<char> >(std::basic_istream<char, std::char_traits<char>
>>&, std::basic_string<char, std::char_traits<char>,
> std::allocator<char> >&, char) (in /usr/lib/libstdc++.so.6.0.13)
> ==10635==    by 0x400D03: threadEntry(void*) (threads2.cpp:12)
> ==10635==    by 0x4C32870: vgDrd_thread_wrapper (drd_pthread_intercepts.c:272)
> ==10635==    by 0x55E8A03: start_thread (pthread_create.c:300)
> ==10635==    by 0x58DD80C: clone (clone.S:112)
> ==10635== Allocation context: BSS section of /usr/lib/libstdc++.so.6.0.13
> ==10635== Other segment start (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635== Other segment end (thread 2)
> ==10635==    (thread finished, call stack no longer available)
> ==10635==
> ==10635==
> ==10635== For counts of detected and suppressed errors, rerun with: -v
> ==10635== ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 39 from 33)
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Valgrind-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/valgrind-users
>

With a bit guesswork: reading from a file in general (and thus also
from std input) is undefined behavior as input will only be delivered
to one thread and you won't be able to control which one.

Bjoern

------------------------------------------------------------------------------

_______________________________________________
Valgrind-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to