This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/12855] Thread safety problems in ios_base::Init
- From: "peturr02 at ru dot is" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 11 Dec 2003 08:18:47 -0000
- Subject: [Bug libstdc++/12855] Thread safety problems in ios_base::Init
- References: <20031031094301.12855.peturr02@ru.is>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From peturr02 at ru dot is 2003-12-11 08:18 -------
I think the patch is fine in general, but this bit seems wrong:
*************** namespace std
*** 80,86 ****
ios_base::Init::Init()
{
! if (_S_ios_base_init == 0)
{
// Standard streams default to synced with "C" operations.
_S_synced_with_stdio = true;
--- 80,86 ----
ios_base::Init::Init()
{
! if (__exchange_and_add(&_S_references, 1) == 0)
{
// Standard streams default to synced with "C" operations.
_S_synced_with_stdio = true;
*************** namespace std
*** 110,124 ****
wcin.tie(&wcout);
wcerr.flags(ios_base::unitbuf);
#endif
-
- _S_ios_base_init = 1;
}
- ++_S_ios_base_init;
}
ios_base::Init::~Init()
{
! if (--_S_ios_base_init == 1)
{
// Catch any exceptions thrown by basic_ostream::flush()
try
--- 110,121 ----
wcin.tie(&wcout);
wcerr.flags(ios_base::unitbuf);
#endif
}
}
ios_base::Init::~Init()
{
! if (__exchange_and_add(&_S_references, -1) == 1)
{
Currently, the constructor sets _S_ios_base_init to 2 on the first run. Each
call after that adds 1, and each call of the destructor subtracts 1. This is
done so that the streams are only constructed once.
It seems to me that with this patch, the first run of the constructor will
set _S_references to 1, but everything else is as before, so that:
#include <ios> // Note: not <iostream>
int main {
{ ios_base::Init i; } // Construct streams
{ ios_base::Init j; } // Constructs streams again
}
This can cause problems for programs that use static constructors to change
settings of the streams, or that perform IO in destructors or atexit()
functions.
There is a testcase that was supposed to check for this condition:
testsuite/27_io/objects/char/5.cc
testsuite/27_io/objects/wchar_t/5.cc
but it probably fails to catch it because <iostream> is included in the
precompiled header, so an Init object gets constructed before static_ob.
(IMHO neither <iostream> nor <cassert> should be included in the precompiled
headers since both can break obscure test cases, such as this one)
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12855