This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
stdio synching and startup code (was Re: segfaults after loading shared libstdc++)
- To: Artem Khodush <kaa at comail dot ru>
- Subject: stdio synching and startup code (was Re: segfaults after loading shared libstdc++)
- From: Phil Edwards <pedwards at disaster dot jaj dot com>
- Date: Tue, 9 Jan 2001 23:17:21 -0500
- Cc: libstdc++ at gcc dot gnu dot org
- References: <013601c079da$b8623850$3737370a@artem>
I'm merging two topics with this one message, because they are starting
to become more and more related.
On Tue, Jan 09, 2001 at 04:23:05AM +0300, Artem Khodush wrote:
>
> But later in the ios_base::Init::Init() (file src/ios.cc), that single filebuf
> is destroyed four times:
That is a little bit odd.
I like your idea of explicitly closing things up just once, but
> + extern filebuf __cfileinit;
> + #ifdef _GLIBCPP_USE_WCHAR_T
> + extern wfilebuf __wfileinit;
> + #endif
is not how we want to do it, I believe. The __cfileinit object is meant
to be local to stdstreams.cc; referencing it by its name from another file
increases coupling unnecessarily.
However, we can get to that same filebuf using member functions, and then
close it up -- *once*, not four times :-) -- using its dtor. The revision
below uses an "__old" pointer.
I had used a similar method in messing with sync_with_stdio(),
which is in the same file. The patch below is a modification of
Artem Khodush's patch to Init() along with my patch to s_w_s().
The testsuite is still happy, plus the example code I used
in http://gcc.gnu.org/ml/libstdc++/2000-12/msg00264.html (the
hello-filesystem-world bit) now does the right thing.
Comments? Artem, does this variation still fix your apache code?
Index: ios.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/src/ios.cc,v
retrieving revision 1.9
diff -c -3 -p -r1.9 ios.cc
*** ios.cc 2001/01/06 02:44:11 1.9
--- ios.cc 2001/01/10 04:04:51
*************** namespace std
*** 126,147 ****
if (++_S_ios_base_init == 1)
{
// NB: std_iostream.h creates the four standard files with
! // default buffers. At this point, we swap out the default
! // buffers for the properly-constructed ones, and dispose of
! // the default buffers.
streambuf* __old;
! _M_cout = new filebuf(1, "stdout", ios_base::out);
_M_cin = new filebuf(0, "stdin", ios_base::in);
_M_cerr = new filebuf(2, "stderr", ios_base::out);
__old = cout.rdbuf(_M_cout);
! __old->~streambuf();
! __old = cin.rdbuf(_M_cin);
! __old->~streambuf();
cin.tie(&cout);
! __old = cerr.rdbuf(_M_cerr);
! __old->~streambuf();
cerr.flags(ios_base::unitbuf);
! __old = clog.rdbuf(_M_cerr);
__old->~streambuf();
#ifdef _GLIBCPP_USE_WCHAR_T
wstreambuf* __wold;
--- 126,144 ----
if (++_S_ios_base_init == 1)
{
// NB: std_iostream.h creates the four standard files with
! // one default buffer (__cfileinit). At this point, we swap
! // out the default buffer for the properly-constructed ones,
! // and close the default buffer.
streambuf* __old;
! _M_cout = new filebuf(1, "stdout", ios_base::out);
_M_cin = new filebuf(0, "stdin", ios_base::in);
_M_cerr = new filebuf(2, "stderr", ios_base::out);
__old = cout.rdbuf(_M_cout);
! cin.rdbuf(_M_cin);
cin.tie(&cout);
! cerr.rdbuf(_M_cerr);
cerr.flags(ios_base::unitbuf);
! clog.rdbuf(_M_cerr);
__old->~streambuf();
#ifdef _GLIBCPP_USE_WCHAR_T
wstreambuf* __wold;
*************** namespace std
*** 149,162 ****
_M_wcin = new wfilebuf(0, "stdin", ios_base::in);
_M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
__wold = wcout.rdbuf(_M_wcout);
! __wold->~wstreambuf();
! __wold = wcin.rdbuf(_M_wcin);
! __wold->~wstreambuf();
wcin.tie(&wcout);
! __wold = wcerr.rdbuf(_M_wcerr);
! __wold->~wstreambuf();
wcerr.flags(ios_base::unitbuf);
! __wold = wclog.rdbuf(_M_wcerr);
__wold->~wstreambuf();
#endif
_M_synced_with_stdio = true;
--- 146,156 ----
_M_wcin = new wfilebuf(0, "stdin", ios_base::in);
_M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
__wold = wcout.rdbuf(_M_wcout);
! wcin.rdbuf(_M_wcin);
wcin.tie(&wcout);
! wcerr.rdbuf(_M_wcerr);
wcerr.flags(ios_base::unitbuf);
! wclog.rdbuf(_M_wcerr);
__wold->~wstreambuf();
#endif
_M_synced_with_stdio = true;
*************** namespace std
*** 322,356 ****
if (!__sync && __ret)
{
// Need to dispose of the buffers created at initialization.
! __ioinit._M_cout->~filebuf();
! __ioinit._M_cin->~filebuf();
! __ioinit._M_cerr->~filebuf();
! __ioinit._M_cout = new filebuf();
! __ioinit._M_cin = new filebuf();
! __ioinit._M_cerr = new filebuf();
! __ioinit._M_cout->open("stdout", ios_base::out);
! __ioinit._M_cin->open("stdin", ios_base::in);
! __ioinit._M_cerr->open("stderr", ios_base::out);
! cout.rdbuf(__ioinit._M_cout);
! cin.rdbuf(__ioinit._M_cin);
! cerr.rdbuf(__ioinit._M_cerr);
cerr.flags(ios_base::unitbuf);
! clog.rdbuf(__ioinit._M_cerr);
#ifdef _GLIBCPP_USE_WCHAR_T
! __ioinit._M_wcout->~wfilebuf();
! __ioinit._M_wcin->~wfilebuf();
! __ioinit._M_wcerr->~wfilebuf();
! __ioinit._M_wcout = new wfilebuf();
! __ioinit._M_wcin = new wfilebuf();
! __ioinit._M_wcerr = new wfilebuf();
! __ioinit._M_wcout->open("wstdout", ios_base::out);
! __ioinit._M_wcin->open("wstdin", ios_base::in);
! __ioinit._M_wcerr->open("wstderr", ios_base::out);
! wcout.rdbuf(__ioinit._M_wcout);
! wcin.rdbuf(__ioinit._M_wcin);
! wcerr.rdbuf(__ioinit._M_wcerr);
wcerr.flags(ios_base::unitbuf);
! wclog.rdbuf(__ioinit._M_wcerr);
#endif
__ioinit._M_synced_with_stdio = false;
}
--- 316,339 ----
if (!__sync && __ret)
{
// Need to dispose of the buffers created at initialization.
! // Build new (ergo non-synchronized) buffers, switch pointers.
! __ioinit._M_cout = new filebuf(1, "stdout", ios_base::out);
! __ioinit._M_cin = new filebuf(0, "stdin", ios_base::in);
! __ioinit._M_cerr = new filebuf(2, "stderr", ios_base::out);
! delete cout.rdbuf(__ioinit._M_cout);
! delete cin.rdbuf(__ioinit._M_cin);
! delete cerr.rdbuf(__ioinit._M_cerr);
cerr.flags(ios_base::unitbuf);
! delete clog.rdbuf(__ioinit._M_cerr);
#ifdef _GLIBCPP_USE_WCHAR_T
! __ioinit._M_wcout = new wfilebuf(1, "wstdout", ios_base::out);
! __ioinit._M_wcin = new wfilebuf(0, "wstdin", ios_base::in);
! __ioinit._M_werrt = new wfilebuf(2, "wstderr", ios_base::out);
! delete wcout.rdbuf(__ioinit._M_wcout);
! delete wcin.rdbuf(__ioinit._M_wcin);
! delete wcerr.rdbuf(__ioinit._M_wcerr);
wcerr.flags(ios_base::unitbuf);
! delete wclog.rdbuf(__ioinit._M_wcerr);
#endif
__ioinit._M_synced_with_stdio = false;
}