Bug 53984 - iostream operation throwing exception when exceptions not enabled
Summary: iostream operation throwing exception when exceptions not enabled
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.6.3
: P3 normal
Target Milestone: 5.5
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-16 16:11 UTC by Pete Chapman
Modified: 2017-09-13 15:50 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 8.0
Known to fail:
Last reconfirmed: 2012-07-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pete Chapman 2012-07-16 16:11:08 UTC
I'm getting an exception thrown in a situation where I believe a failbit should be set instead.
Is my expectation wrong?

-------------------
#include <fstream>
#include <sstream>

int main()
{
    std::ifstream in(".");
    std::ostringstream out;
    if (in)
      in >> out.rdbuf();
}
-------------------


terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_filebuf::underflow error reading the file
Aborted (core dumped)
Comment 1 Pete Chapman 2012-07-16 17:00:10 UTC
Even simpler:

-------------------
#include <fstream>
int main()
{
        std::ifstream in(".");
        int x;
        if (in)
          in >> x;
}
-------------------
Comment 2 Jonathan Wakely 2012-07-16 17:26:39 UTC
Confirmed, I'm not sure filebuf::underflow should throw on invalid byte sequences either.
Comment 3 Tomalak Geret'kal 2013-12-04 16:05:04 UTC
Another testcase was proposed under the following Stack Overflow question:

  http://stackoverflow.com/q/20371956/560648

The answer to that question was a link to this bug.
Comment 4 Igor 2014-05-20 22:45:29 UTC
This is a really evil bug.  I wonder why the Importance is not higher.

This may crash programs that try to read many /proc files on Linux.


~$ g++ -x c++ -o test - <<EOF
#include <fstream>
#include <unistd.h>
int main(int argc, char *argv[])
{
    std::ifstream in(argv[1]);
    sleep(4);
    std::string s;
    if (in)
      in >> s;
    return 0;
}
EOF

~$ sleep 2 & ./test "/proc/${!}/stat"

terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_filebuf::underflow error reading the file
Aborted (core dumped)
Comment 5 Roger Orr 2016-05-05 08:39:17 UTC
Still fails with gcc 6.1

Are there any plans on how (and when) to fix this, fairly serious, fault?
Comment 6 David Rodriguez Ibeas 2017-04-28 14:16:54 UTC
Still failling 6.2.

Any plans to look at this one?
Comment 7 Jonathan Wakely 2017-04-28 17:47:23 UTC
Eventually. I tried removing the throws and got a bunch of test failures:

FAIL: 27_io/basic_filebuf/overflow/char/9182-2.cc execution test
FAIL: 27_io/basic_filebuf/seekoff/wchar_t/3.cc execution test
FAIL: 27_io/basic_filebuf/seekpos/wchar_t/1.cc execution test
FAIL: 27_io/basic_filebuf/sync/char/9182-1.cc execution test
FAIL: 27_io/basic_filebuf/underflow/wchar_t/11544-1.cc execution test
FAIL: 27_io/basic_filebuf/underflow/wchar_t/11544-2.cc execution test
FAIL: 27_io/basic_filebuf/underflow/wchar_t/11603.cc execution test
Comment 8 Jonathan Wakely 2017-07-25 19:51:57 UTC
FAIL: 27_io/basic_filebuf/overflow/char/9182-2.cc execution test

This fails because it explicitly tests for an exception:

  try
    {
      fbuf1.sputn("ison", 4);
      fbuf1.pubsync();
      VERIFY( false );
    }
  catch (std::exception&)
    {
    }


FAIL: 27_io/basic_filebuf/seekoff/wchar_t/3.cc execution test

This also fails because it explicitly tests for an exception:

  try
    {
      // seekoff should flush the output sequence, which will fail
      // if the output buffer contains illegal characters.
      fb.pubseekoff(0, ios_base::cur);
      VERIFY( false );
    }
  catch (std::exception&)
    {
    }


FAIL: 27_io/basic_filebuf/seekpos/wchar_t/1.cc execution test

This also tests for an exception:

  try
    {
      fb.pubseekpos(pos);
      VERIFY( false );
    }
  catch (std::exception&)
    {
    }



FAIL: 27_io/basic_filebuf/sync/char/9182-1.cc execution test

And again:


  try
    {
      fbuf1.sputn("onne", 4);
      fbuf1.close();
      VERIFY( false );
    }
  catch (std::exception&)
    {
    }



FAIL: 27_io/basic_filebuf/underflow/wchar_t/11544-1.cc execution test
FAIL: 27_io/basic_filebuf/underflow/wchar_t/11544-2.cc execution test

These both check for a bad stream state:

  VERIFY( in.good() );
  in.get();
  VERIFY( !in.good() );
  VERIFY( in.bad() );
  VERIFY( !in.eof() );


FAIL: 27_io/basic_filebuf/underflow/wchar_t/11603.cc execution test

This fails because we have this:

  try
    {
      wfilebuf::int_type ret = fb.pub_underflow();
      VERIFY( ret != wfilebuf::traits_type::eof() );
      fb.sbumpc();
      ret = fb.pub_underflow();
      VERIFY( ret == wfilebuf::traits_type::eof() );
    }
  catch (...)
    { }

The first VERIFY is never reached because we throw in underflow. The test seems broken.


Several of these tests are explicitly checking for exceptions, so the current behaviour of throwing on invalid byte sequences (comment 2) is clearly by design.

I don't think the problem here is actually in basic_filebuf. I think filebuf is allowed to throw if there's an I/O error. I think the problem is that basic_istream::sentry doesn't handle exceptions that happen while skipping whitespace:

#include <streambuf>
#include <istream>

struct SB : std::streambuf {
  int_type underflow() override { throw 1; }
};

int main()
{
  SB sb;
  std::istream is(&sb);
  int i;
  is >> i;
}

This seems easy to fix.
Comment 9 Jonathan Wakely 2017-07-25 20:36:38 UTC
Author: redi
Date: Tue Jul 25 20:36:06 2017
New Revision: 250545

URL: https://gcc.gnu.org/viewcvs?rev=250545&root=gcc&view=rev
Log:
PR libstdc++/53984 handle exceptions in basic_istream::sentry

	PR libstdc++/53984
	* include/bits/basic_ios.h (basic_ios::_M_setstate): Adjust comment.
	* include/bits/istream.tcc (basic_istream::sentry): Handle exceptions
	during construction.
	* include/std/istream: Adjust comments for formatted input functions
	and unformatted input functions.
	* testsuite/27_io/basic_fstream/53984.cc: New.
	* testsuite/27_io/basic_istream/sentry/char/53984.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc
    trunk/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/basic_ios.h
    trunk/libstdc++-v3/include/bits/istream.tcc
    trunk/libstdc++-v3/include/std/istream
Comment 10 Jonathan Wakely 2017-07-25 21:05:39 UTC
Fixed on trunk. We might want to backport this to active branches too.
Comment 11 Jonathan Wakely 2017-07-26 22:06:45 UTC
Author: redi
Date: Wed Jul 26 22:06:13 2017
New Revision: 250594

URL: https://gcc.gnu.org/viewcvs?rev=250594&root=gcc&view=rev
Log:
PR libstdc++/53984 fix failing test

	PR libstdc++/53984
	* testsuite/27_io/basic_fstream/53984.cc: Fix test.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc
Comment 12 Jonathan Wakely 2017-09-04 16:52:57 UTC
Author: redi
Date: Mon Sep  4 16:52:25 2017
New Revision: 251675

URL: https://gcc.gnu.org/viewcvs?rev=251675&root=gcc&view=rev
Log:
PR libstdc++/53984 handle exceptions in basic_istream::sentry

Backport from mainline
2017-07-25  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/53984
	* include/bits/basic_ios.h (basic_ios::_M_setstate): Adjust comment.
	* include/bits/istream.tcc (basic_istream::sentry): Handle exceptions
	during construction.
	* include/std/istream: Adjust comments for formatted input functions
	and unformatted input functions.
	* testsuite/27_io/basic_fstream/53984.cc: New.
	* testsuite/27_io/basic_istream/sentry/char/53984.cc: New.

Added:
    branches/gcc-6-branch/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc
    branches/gcc-6-branch/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc
Modified:
    branches/gcc-6-branch/libstdc++-v3/ChangeLog
    branches/gcc-6-branch/libstdc++-v3/include/bits/basic_ios.h
    branches/gcc-6-branch/libstdc++-v3/include/bits/istream.tcc
    branches/gcc-6-branch/libstdc++-v3/include/std/istream
Comment 13 Jonathan Wakely 2017-09-04 17:09:32 UTC
Author: redi
Date: Mon Sep  4 17:09:01 2017
New Revision: 251679

URL: https://gcc.gnu.org/viewcvs?rev=251679&root=gcc&view=rev
Log:
PR libstdc++/53984 handle exceptions in basic_istream::sentry

Backport from mainline
2017-07-25  Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/53984
	* include/bits/basic_ios.h (basic_ios::_M_setstate): Adjust comment.
	* include/bits/istream.tcc (basic_istream::sentry): Handle exceptions
	during construction.
	* include/std/istream: Adjust comments for formatted input functions
	and unformatted input functions.
	* testsuite/27_io/basic_fstream/53984.cc: New.
	* testsuite/27_io/basic_istream/sentry/char/53984.cc: New.

Added:
    branches/gcc-5-branch/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc
    branches/gcc-5-branch/libstdc++-v3/testsuite/27_io/basic_istream/sentry/char/53984.cc
Modified:
    branches/gcc-5-branch/libstdc++-v3/ChangeLog
    branches/gcc-5-branch/libstdc++-v3/include/bits/basic_ios.h
    branches/gcc-5-branch/libstdc++-v3/include/bits/istream.tcc
    branches/gcc-5-branch/libstdc++-v3/include/std/istream
Comment 14 Jonathan Wakely 2017-09-04 17:18:14 UTC
Fixed for 5.5, 6.5 and 7.3
Comment 15 Aldy Hernandez 2017-09-13 15:50:21 UTC
Author: aldyh
Date: Wed Sep 13 15:49:50 2017
New Revision: 252105

URL: https://gcc.gnu.org/viewcvs?rev=252105&root=gcc&view=rev
Log:
PR libstdc++/53984 fix failing test

	PR libstdc++/53984
	* testsuite/27_io/basic_fstream/53984.cc: Fix test.

Modified:
    branches/range-gen2/libstdc++-v3/ChangeLog
    branches/range-gen2/libstdc++-v3/testsuite/27_io/basic_fstream/53984.cc