This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/16655] New: Segmentation fault in the std::ofstream destructor


On some file systems (for example on AFS), the ofstream destructor crashes the
application if there is no space left on that FS. This happens because it calls
the fclose() function 2 times. 
In more details the problem is that in case of no space left on AFS the fflush()
succeeds and only fclose() fails. In this case:

1. the __basic_file<char>::close() is called twice - first time by the
basic_filebuf<char, std::char_traits<char> >::close() and second time by the
__basic_file<char> destructor.
2. in the first call the fclose() fails and the _M_cfile is not set to 0.
3. in the second call __basic_file<char>::is_open() returns true because the
_M_cfile is not 0 and the fclose() is called second time and tries to use the
memory which was already freed by the previous invocation of the fclose().
4. Program crashes.

Here is the program, which reproduces the bug:

#include <fstream>
#include <iostream>

using namespace std;

int main()
{
    ofstream foo( "foo.bar", std::ios::out | std::ios::trunc );
    
    for ( int i = 0; i < 1000000; i++ )
	foo << "hello";
    
    cout << "foo.good() = " << foo.good() << endl;
    cout << "foo.bad() = " << foo.bad() << endl;
    cout << "foo.eof() = " << foo.eof() << endl;
    cout << "foo.fail() = " << foo.fail() << endl << endl;
    
    foo.flush();
    
    cout << "foo.good() = " << foo.good() << endl;
    cout << "foo.bad() = " << foo.bad() << endl;
    cout << "foo.eof() = " << foo.eof() << endl;
    cout << "foo.fail() = " << foo.fail() << endl << endl;
    
    foo.close();
    
    cout << "foo.good() = " << foo.good() << endl;
    cout << "foo.bad() = " << foo.bad() << endl;
    cout << "foo.eof() = " << foo.eof() << endl;
    cout << "foo.fail() = " << foo.fail() << endl;
    
    return 0;
}


The output is (on AFS with not enough space left):

foo.good() = 1
foo.bad() = 0
foo.eof() = 0
foo.fail() = 0

foo.good() = 1
foo.bad() = 0
foo.eof() = 0
foo.fail() = 0

foo.good() = 0
foo.bad() = 0
foo.eof() = 0
foo.fail() = 1
Segmentation fault (core dumped)

The problem does not appear for a local file system because in this case the
fflush() fails and destructor works correctly.

-- 
           Summary: Segmentation fault in the std::ofstream destructor
           Product: gcc
           Version: 3.2
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: Serguei dot Kolos at cern dot ch
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i386-pc-linux-gnu
  GCC host triplet: i386-pc-linux-gnu
GCC target triplet: i386-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16655


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]