Bug 10081

Summary: basic_ios::_M_cache_locale leaves NULL members in the face of unknown locales
Product: gcc Reporter: Pétur Runólfsson <peturrun>
Component: libstdc++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs
Priority: P3    
Version: 3.2.2   
Target Milestone: 3.3.3   
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Known to work:
Known to fail: Last reconfirmed: 2003-06-09 15:21:57
Attachments: iosconsbug.cc

Description Pétur Runólfsson 2003-03-14 12:06:00 UTC
The constructor basic_ios::basic_ios() doesn't initialize the members _M_fctype, _M_fnumput and _M_fnumget, leading to crashes when these members are accessed later.

Release:
gcc-3.2.2

Environment:
Red Hat Linux 8.0

How-To-Repeat:
See attachment. This only checks _M_fctype, to test for the others, numpunct must be specialized for the character type in use.
Comment 1 Andrew Pinski 2003-05-27 18:47:12 UTC
On the mainline (20030527) I get an exception thrown:
terminate called after throwing an instance of 'std::bad_cast'
  what():  St8bad_cast
(gdb) bt
#0  0x420292d1 in kill () from /lib/i686/libc.so.6
#1  0x420290ba in raise () from /lib/i686/libc.so.6
#2  0x4202a862 in abort () from /lib/i686/libc.so.6
#3  0x400aa4e3 in __gnu_cxx::__verbose_terminate_handler() () at /home/gates/
pinskia/src/gnu/gcc/src/libstdc++-v3/libsupc++/vterminate.cc:96
#4  0x400a8055 in __cxxabiv1::__terminate(void (*)()) (handler=0x400aa3f0 <
__gnu_cxx::__verbose_terminate_handler()>) at /home/gates/pinskia/src/gnu/gcc/src/
libstdc++-v3/libsupc++/eh_terminate.cc:43
#5  0x400a8092 in std::terminate() () at /home/gates/pinskia/src/gnu/gcc/src/libstdc++-v3/
libsupc++/eh_terminate.cc:53
#6  0x400a8212 in __cxa_throw (obj=0x400ad2db, tinfo=0x0, dest=0) at /home/gates/
pinskia/src/gnu/gcc/src/libstdc++-v3/libsupc++/eh_throw.cc:80
#7  0x40061c45 in std::__throw_bad_cast() () at typeinfo:138
#8  0x0804a97b in __check_facet<std::ctype<__gnu_cxx_test::pod_char> > (__f=0x0) at 
localefwd.h:187
#9  0x0804a504 in sentry (this=0xbffec13b, __in=@0xbffec180, __noskipws=false) at 
istream.tcc:56
#10 0x080494e4 in std::basic_istream<__gnu_cxx_test::pod_char, std::char_traits<
__gnu_cxx_test::pod_char> >& std::operator>><__gnu_cxx_test::pod_char, 
std::char_traits<__gnu_cxx_test::pod_char>, std::allocator<__gnu_cxx_test::pod_char> >
(std::basic_istream<__gnu_cxx_test::pod_char, std::char_traits<
__gnu_cxx_test::pod_char> >&, std::basic_string<__gnu_cxx_test::pod_char, 
std::char_traits<__gnu_cxx_test::pod_char>, std::allocator<__gnu_cxx_test::pod_char> >
&) (__in=@0xbffec180, __str=@0xbffec170) at istream.tcc:1102
#11 0x0804921a in main () at pr10081.cc:266
Comment 2 Dara Hazeghi 2003-06-08 08:15:25 UTC
Confirmed with branch and mainline (20030605).
Comment 3 Phil Edwards 2003-06-09 15:21:56 UTC
Well, don't say that the members aren't being initialized, because they are:

      explicit
      basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
      : ios_base(), _M_ctype(0), _M_num_put(0), _M_num_get(0)
      { this->init(__sb); }

(The names of the variables were changed mid-May.)

The crash is because _M_ctype is still NULL when op>> is executed, leading to
a NULL facet argument in __check_facet.  basic_ios::init makes an attempt to
cache the facet, but since has_facet is (I expect) false for pod_char, the
members are not assigned new values.

I don't know what the Right Thing is here.
Comment 4 Pétur Runólfsson 2003-06-30 11:00:17 UTC
Phil Edwards wrote:
> Well, don't say that the members aren't being initialized, because
> they are:
>
>      explicit
>      basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
>      : ios_base(), _M_ctype(0), _M_num_put(0), _M_num_get(0)
>      { this->init(__sb); }
>
> (The names of the variables were changed mid-May.)

Revision 1.18 of basic_ios.h had this:

      basic_ios() : ios_base()
      { }

but after this checkin:
Fri Mar 28 19:45:44 2003 UTC (2 months, 4 weeks ago) by bkoz=3D20
the constructor reads thus:

      basic_ios() : ios_base(), _M_fctype(0), _M_fnumput(0),
      _M_fnumget(0)
      { }

So it seems that the bug has been fixed.

> The crash is because _M_ctype is still NULL when op>> is executed,
> leading to a NULL facet argument in __check_facet.
> basic_ios::init makes an attempt to cache the facet, but since
> has_facet is (I expect) false for pod_char, the members are not
> assigned new values.
>
> I don't know what the Right Thing is here.

The reason that the test case still crashes is this:
operator>>(basic_istream&, basic_string&) calls
basic_istream::sentry::sentry() which behaves "as if" it called
use_facet<ctype<char_type> >(getloc()). Since the locale returned by
getloc() does not contain the requested facet, use_facet throws an
exception, and since there is no matching catch block, the program
crashes.

Wether operator>> or the sentry constructor should catch the exception
is the subject of many other bug reports (and DRs). I think this bug
can be closed, but a
  try
    {
    [ ... ]
    }
  catch (exception) { }=3D20
needs to be added to the testcase if it is added to the testsuite
(probably a good idea, since there are currently very few testcases
for character types other than char or wchar_t).

Regards,
Petur
Comment 5 GCC Commits 2003-10-20 22:11:46 UTC
Subject: Bug 10081

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	bkoz@gcc.gnu.org	2003-10-20 22:11:41

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/ext: pod_char_traits.h 
	libstdc++-v3/testsuite: testsuite_hooks.cc testsuite_hooks.h 
	libstdc++-v3/testsuite/22_locale/numpunct/members/pod: 1.cc 2.cc 
Added files:
	libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/pod: 
	                                                                         10081-in.cc 
	                                                                         10081-out.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/pod: 
	                                                                      3983-1.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/pod: 
	                                                                     3983-2.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/pod: 
	                                                                 3983-3.cc 
	libstdc++-v3/testsuite/27_io/basic_istream/sentry/pod: 1.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/sentry/pod: 1.cc 
Removed files:
	libstdc++-v3/testsuite/27_io/basic_istream/sentry/char: 
	                                                        3983-fstream.cc 
	                                                        3983-sstream.cc 
	libstdc++-v3/testsuite/27_io/basic_ostream/sentry/char: 
	                                                        3983-fstream.cc 
	                                                        3983-sstream.cc 

Log message:
	2003-10-20  Benjamin Kosnik  <bkoz@redhat.com>
	
	PR libstdc++/10081
	* testsuite_hooks.h: Add pod_type, ctype and numpunct specializations.
	* testsuite_hooks.cc: Same.
	* 22_locale/numpunct/members/pod/1.cc: Edit.
	* 22_locale/numpunct/members/pod/2.cc: Same.
	* 27_io/basic_istream/sentry/char/3983-fstream.cc: Move ...
	* 27_io/basic_istream/sentry/char/3983-sstream.cc: Move ...
	* 27_io/basic_istream/extractors_arithmetic/pod/3983-1.cc: Here.
	* 27_io/basic_istream/extractors_character/pod/3983-2.cc: Here.
	* 27_io/basic_istream/extractors_other/pod/3983-3.cc: Here.
	* 27_io/basic_ostream/sentry/char/3983-fstream.cc: Remove.
	* 27_io/basic_ostream/sentry/char/3983-sstream.cc: Remove.
	* 27_io/basic_istream/sentry/pod/1.cc: New.
	* 27_io/basic_ostream/sentry/pod/1.cc: New.
	* 21_strings/basic_string/inserters_extractors/pod/10081-in.cc: New.
	* 21_strings/basic_string/inserters_extractors/pod/10081-out.cc: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.2028&r2=1.2029
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/ext/pod_char_traits.h.diff?cvsroot=gcc&r1=1.3&r2=1.4
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/testsuite_hooks.cc.diff?cvsroot=gcc&r1=1.16&r2=1.17
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/testsuite_hooks.h.diff?cvsroot=gcc&r1=1.23&r2=1.24
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/pod/10081-in.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/21_strings/basic_string/inserters_extractors/pod/10081-out.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/1.cc.diff?cvsroot=gcc&r1=1.2&r2=1.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/22_locale/numpunct/members/pod/2.cc.diff?cvsroot=gcc&r1=1.2&r2=1.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_arithmetic/pod/3983-1.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_character/pod/3983-2.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/extractors_other/pod/3983-3.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/3983-fstream.cc.diff?cvsroot=gcc&r1=1.8&r2=NONE
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/3983-sstream.cc.diff?cvsroot=gcc&r1=1.4&r2=NONE
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_istream/sentry/pod/1.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/sentry/char/3983-fstream.cc.diff?cvsroot=gcc&r1=1.8&r2=NONE
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/sentry/char/3983-sstream.cc.diff?cvsroot=gcc&r1=1.4&r2=NONE
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/basic_ostream/sentry/pod/1.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 6 Benjamin Kosnik 2003-10-20 22:20:24 UTC
Fixed and testecases added on mainline, patched on gcc-3_3-branch.

-benjamin
Comment 7 GCC Commits 2003-10-21 02:31:35 UTC
Subject: Bug 10081

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	bkoz@gcc.gnu.org	2003-10-21 02:31:32

Modified files:
	libstdc++-v3   : ChangeLog 
	libstdc++-v3/include/bits: basic_ios.h 

Log message:
	2003-10-20  Benjamin Kosnik  <bkoz@redhat.com>
	
	PR libstdc++/10081
	* include/bits/basic_ios.h (basic_ios::basic_ios): Initialize
	_M_fctype, _M_fnumput, _M_fnumget.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.1464.2.152&r2=1.1464.2.153
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_ios.h.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.14.2.5&r2=1.14.2.6

Comment 8 Andrew Pinski 2003-10-21 15:33:55 UTC
Fixed for 3.3.3.