|
From: Jorge M. <jor...@gm...> - 2010-05-27 02:29:25
|
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)
|
|
From: Bjoern D. <bjo...@go...> - 2010-05-27 06:17:35
|
2010/5/27 Jorge Moraleda <jor...@gm...>:
> 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
> Val...@li...
> 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
|
|
From: Gaetano M. <me...@gm...> - 2010-05-27 18:41:16
|
On Thu, May 27, 2010 at 8:17 AM, Bjoern Doebel <bjo...@go...> wrote: > 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. That's wrong, the two different threads use a different "file descriptor", that would be a "race" if one writes and another one read, that is not this the case. G. |
|
From: Bart V. A. <bva...@ac...> - 2010-05-27 10:42:19
|
On Thu, May 27, 2010 at 4:29 AM, Jorge Moraleda
<jor...@gm...> wrote:
>
> 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)
> [ ... ]
Strange. I have tried to reproduce this with gcc 4.4.4 (which includes
libstdc++.so.6.0.13), but did not see any race reports.
Does inserting two pthread_join() calls between pthread_create() and
pthread_exit() in main() help ?
Bart.
|
|
From: Jorge M. <jor...@gm...> - 2010-05-28 21:59:16
|
On Thu, May 27, 2010 at 3:42 AM, Bart Van Assche <bva...@ac...> wrote:
> On Thu, May 27, 2010 at 4:29 AM, Jorge Moraleda
> <jor...@gm...> wrote:
>>
>> 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)
>> [ ... ]
Bart, thank you for all your help.
> Strange. I have tried to reproduce this with gcc 4.4.4 (which includes
> libstdc++.so.6.0.13), but did not see any race reports.
I observe the same thing you do. My original report was using gcc
4.4.1. When I compile the test program with 4.4.4 I don't see the race
reports either. However, my real program (which is not a small test
that I can submit) does produce race conditions even when compiled
with gcc 4.4.4. The race conditions are in different places every
time, and never in the stringstream/getline code, but the "other
segment" contains in all cases a block of code that looks essentially
the same as the one in the test case. I wrote a custom alternative not
using stringstreams or getline in that block of code, and all the race
conditions are gone, so this problem is solved for me, but I still
would like to find out what the problem was. I have tried to refine
the test program so that it would reproduce the race conditions, but I
haven't been able to.
>
> Does inserting two pthread_join() calls between pthread_create() and
> pthread_exit() in main() help ?
I tried this in the gcc 4.4.1 system and it does not help.
>
> Bart.
>
|