operator>>(istream, double) is not thread safe.
The following small program demonstrates the issue (proved on mingw32-g++ 3.4.4, 3.4.5 and 4.4.0):
$ g++ -mthreads -o thread_bug thread_bug.cc
$ .\thread_bug.exe
This will lead to one of the following error messages:
- The instruction at "0x77c3330c" referenced memory at "0x00000000". The memory could not be "read."
- The instruction at "0x77c33509" referenced memory at "0x00000000". The memory could not be "read."
#include <windows.h>
#include <iostream>
#include <sstream>
DWORD WINAPI task(LPVOID lpArg) {
double x ;
for (int k=0 ; k<10000 ; ++k) {
std::istringstream is("10") ;
is >> x ;
}
std::cout << "task ended: " << x << std::endl ;
return 0 ;
}
int main() {
const int N=10 ;
HANDLE hHandles[N] ;
for (int k=0 ; k<N ; ++k) {
hHandles[k]=CreateThread(NULL, 0, task, NULL, 0, NULL) ;
}
for (int k=0 ; k<N ; ++k) WaitForSingleObject(hHandles[k], INFINITE) ;
return 0 ;
}
* The same program works fine with:
- MSVC++ 2008,
- g++ 4.3.2 on linux 64 (using pthreads),
- intel compiler 10.0 on linux 64 (using pthreads).
* There is no bug reading an "int". Reading double leads to an issue.
* mingw32-g++ links to msvcrt.dll where msvc++ 2008 links to msvcp90.dll and msvcr90.dll.
* Same bug reading from a file.
* No bug with pure C code reading from a file with fscanf.
The bug appears in these conditions:
* platform:
Windows XP SP3,
* gcc version:
Using built-in specs.
Target: mingw32
Configured with: ../gcc-4.4.0/configure --enable-languages=c,ada,c++,fortran,java,objc,obj-c++ --disable-sjlj-exceptions --enable-shared --enable-libgcj --enable-libgomp --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --prefix=/mingw --with-gmp=/mingw/src/gmp/root --with-mpfr=/mingw/src/mpfr/root --build=mingw32
Thread model: win32
gcc version 4.4.0 (GCC)
* binutils:
GNU ld (GNU Binutils) 2.19.1
* build Environment
Microsoft Shell (%SystemRoot%\system32\cmd.exe)
The bug also appears using the cygwin platform and g++ 3.4.4 with -mno-cygwin flag.
What is the version number of your msvcrt.dll (look at the file properties to get the version from the versioninfo resource.)
Older msvcrt.dll's (eg 6.10.8924.0) had thread-locking problems with setlocale that causes a similar bug in libstdc++. The msvcrt.dll that ships with Vista (mine has version number 7.0.6001.18000) works fine.
My msvcrt.dll version is 7.0.2600.5512.
Do you reproduce the bug on your Vista?
I cannot reproduce the error with gcc 4.5.0 on my Vista laptop. I will try older versions of gcc when I get home.
Danny
I tested the program compiled on XP and runned on Vista with version 7.0.6002.18005 of msvcrt.dll: no issue.
Does this mean it is a Windows bug and mingw has nothing to do with it? Is there any workaround for machine using older version of msvcrt.dll?
I'm seeing this exact behavior using the latest MinGW release (20110211, g++ 4.5.2) on Windows XP (automatic updates enabled), msvcrt.dll 7.0.2600.5512.
Work-around: If you serialize access to every istream (istringstream, istrstream, ifstream), locking the mutex from before its created until after it's destructed, then multi-threaded access works. Anything less crashes the app.