segfaults after loading shared libstdc++
Artem Khodush
kaa@comail.ru
Mon Jan 8 16:10:00 GMT 2001
Hi guys,
I think i've found something weird in libstdc++ static constructors.
In my case, it causes apache to segfault in free() shortly after loading
module written in c++. It's very likely that this is the same bug that causes
problems reported in
http://gcc.gnu.org/ml/libstdc++/2000-10/msg00148.html
http://gcc.gnu.org/ml/libstdc++/2000-11/msg00027.html
In src/stdstreams.cc, predefined streams are all created with the same filebuf:
filebuf __cfileinit;
istream cin(&__cfileinit);
ostream cout(&__cfileinit);
ostream cerr(&__cfileinit);
ostream clog(&__cfileinit);
But later in the ios_base::Init::Init() (file src/ios.cc), that single filebuf
is destroyed four times:
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();
Unfortunately, I can't figure out what really happens there because my gdb
goes mad when I try to step through this code, but since the intent is just
to free resources allocated in __cfileinit, I propose the following patch
(which solves my problem with apache):
2001-01-08 Artem Khodush <kaa@comail.ru>
* src/ios.cc (ios_base::Init::Init): Call __cfileinit.close() directly
instead of filebuf destructors. Do the same for __wfileinit.
*** libstdc++-v3/src/ios.cc.original Tue Jan 9 00:19:23 2001
--- libstdc++-v3/src/ios.cc Tue Jan 9 01:33:14 2001
***************
*** 126,168 ****
ios_base::failure::what() const throw()
{ return _M_name; }
ios_base::Init::Init()
{
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;
_M_wcout = new wfilebuf(1, "stdout", ios_base::out);
_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
}
}
--- 126,165 ----
ios_base::failure::what() const throw()
{ return _M_name; }
+ extern filebuf __cfileinit;
+ #ifdef _GLIBCPP_USE_WCHAR_T
+ extern wfilebuf __wfileinit;
+ #endif
+
ios_base::Init::Init()
{
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.
! _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);
! cout.rdbuf(_M_cout);
! cin.rdbuf(_M_cin);
cin.tie(&cout);
! cerr.rdbuf(_M_cerr);
cerr.flags(ios_base::unitbuf);
! clog.rdbuf(_M_cerr);
! __cfileinit.close();
#ifdef _GLIBCPP_USE_WCHAR_T
_M_wcout = new wfilebuf(1, "stdout", ios_base::out);
_M_wcin = new wfilebuf(0, "stdin", ios_base::in);
_M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
! wcout.rdbuf(_M_wcout);
! wcin.rdbuf(_M_wcin);
wcin.tie(&wcout);
! wcerr.rdbuf(_M_wcerr);
wcerr.flags(ios_base::unitbuf);
! wclog.rdbuf(_M_wcerr);
! __wfileinit.close();
#endif
}
}
More information about the Libstdc++
mailing list