From: SourceForge.net <no...@so...> - 2005-02-15 19:48:41
|
Bugs item #944512, was opened at 2004-04-30 02:31 Message generated for change (Comment added) made by dannysmith You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=944512&group_id=2435 Category: gcc Group: None Status: Open Resolution: Accepted Priority: 5 Submitted By: Christoph Wiedemann (wiedeman) Assigned to: Danny Smith (dannysmith) Summary: ostringstream + threads Initial Comment: Hi, std::ostringstream doesn't seem to be reentrant. I have a minimal test case: // myexe.cpp #include <iostream> #include <sstream> using namespace std; #include <windows.h> #include <winbase.h> void run() { int k = 0; while(1) { ostringstream s; s << k++; k %= 10; } } int main(int argc, char **argv) { DWORD id1, id2; CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&run, 0, 0, &id1); run(); return 0; } // end myexe.cpp Compiling with g++ -g -mthreads -c -o myexe.o myexe.cpp g++ -mthreads -mconsole -o myexe.exe myexe.o and executing myexe.exe results in an Access Violation with the (broken) call stack: Call stack: 78002827 msvcrt.dll:78002827 strcat Windows 2000 (SP 2) Mingw installer is MinGW-3.1.0-1.exe gcc -v: Reading specs from C:/MinGW/Bin/../lib/gcc-lib/mingw32/3.2.3/specs Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c++,f77,o bjc --disable-win32-registry --disable-shared --enable-sjlj-exceptions Thread model: win32 gcc version 3.2.3 (mingw special 20030504-1) ld -v: GNU ld version 2.13.90 20030111 Thank you, Christoph ---------------------------------------------------------------------- >Comment By: Danny Smith (dannysmith) Date: 2005-02-16 08:48 Message: Logged In: YES user_id=11494 I didn't meqn the snippet I sent to be interpreted as a workaround, rather as a reduced testcase that also fails (even without stringstreams) I think the only quick solution is to use your own float-to- string conversion. If your desparate I can provide a newer libstdc++.a that should work with G++-3.4.2 that has the fix. The float conversion is also much faster with the newer lib. Danny ---------------------------------------------------------------------- Comment By: John D. Lomonaco (jdlomonaco) Date: 2005-02-16 02:52 Message: Logged In: YES user_id=1217330 Danny, Again, thank you for the quick come back as we are on a fairly tight schedule. I'm not sure, however, how to apply the changes in the modified minimal program you included into our use of the ostringstream when appending a float. Would it be as shown in the following code segment? #include <windows.h> #include <winbase.h> #include <string.h> #include <malloc.h> #include <locale.h> . . void function (void) { ostringstream osTemp; . . char* __old = setlocale(LC_ALL, NULL); char* __sav = (char*) malloc(strlen(__old) + 1); strcpy(__sav, __old); setlocale(LC_ALL, "C"); osTemp << 1.0f; // A function actually supplies the float. setlocale(LC_ALL, __sav); free (__sav); . . } Will this fix the problem even with GCC version 3.2.3? This change will require a good deal of edititing everywhere we use ostringstream even if we use macros or an object (and we use this a lot). So I have to ask, how firm is the date on version 3.4.4? Thanks, John ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2005-02-15 09:51 Message: Logged In: YES user_id=11494 Hi, the problem you report actually is a CRT problem with setlocale. libstdc++'s conversion of float to string calls setlocale to make sure that LC_NUMERIC is set to "C", then resets it to old value The repeated calls to setlocale by the conversion in your loop eventually break the locking/unlocking of thread-local locale data Try #include <windows.h> #include <winbase.h> #include <string.h> #include <malloc.h> #include <locale.h> void run() { while(1) { char* __old = setlocale(LC_ALL, NULL); char* __sav = (char*) malloc(strlen(__old) + 1); strcpy(__sav, __old); setlocale(LC_ALL, "C"); // snprintf a number setlocale(LC_ALL, __sav); free (__sav); } } int main(int argc, char **argv) { DWORD id1, id2; CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&run, 0, 0, &id1); run(); return 0; } The bug is avoided by very recent patch to libstc++, so will not cause probelm with release of gcc 3.4.4 ( another month or so) Danny. ---------------------------------------------------------------------- Comment By: John D. Lomonaco (jdlomonaco) Date: 2005-02-15 03:12 Message: Logged In: YES user_id=1217330 OOPs, (I somehow submitted my append prior to finishing) The complete code segment shown below even works with GCC version 3.2.3 but its a little messy with respect to setting percission of the float in the stream. I included formating for the percission I desired. ostringstream osTemp; . . char buff[6]; sprintf (buff, "%4.2f", 1.0f); osTemp << buff; . . John ---------------------------------------------------------------------- Comment By: John D. Lomonaco (jdlomonaco) Date: 2005-02-15 03:05 Message: Logged In: YES user_id=1217330 Danny, Thanks for the confirmation. I looked at the down loads and could not find a GCC version 4.0.0. When will it be available? We are on a schedule with my current project. By the way I have verified a "work around" by using sprintf to convert and buffer a float into a char * then concatinating this to the ostringstream. char buff[6]; sprintf (buff, "%4.2f", 1.0f); osTemp << buff; ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2005-02-12 11:34 Message: Logged In: YES user_id=11494 I can confiorm jdlomonaco's report that it is still broken, using double in modified testcase, with gcc 3.4.2 and 3.4.4. GCC 4.0.0 works but it uses a different allocator. Danny ---------------------------------------------------------------------- Comment By: John D. Lomonaco (jdlomonaco) Date: 2005-02-12 08:45 Message: Logged In: YES user_id=1217330 I am looking at this problem with interest. It's status is closed. However, We are currently experiencing the same problem with ostringstream with float concatinations to the stream. I also tried concatinating int and it failed also but char did not. We currently compile with version 3.2.3 for our builds. However, we loaded the 3.4.2 version of the compiler on one of our PCs and compiled with it. Floats still fail with the same error. Our test system runs Windows XP. Any help will be appreciated. ---------------------------------------------------------------------- Comment By: Danny Smith (dannysmith) Date: 2004-04-30 19:29 Message: Logged In: YES user_id=11494 I don't have gcc-3.2.3 anymore, but on 3.3.3 and 3.4.0 and gcc trunk your testcase runs without problem, so I'll close this bug as fixed. Danny ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=944512&group_id=2435 |