This is the mail archive of the libstdc++@sources.redhat.com mailing list for the libstdc++ project.


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

Re: How to ... also libstdc++ bug report: memory leak at filebuf close on error.


Phil Edwards wrote:

> On Fri, Sep 22, 2000 at 03:52:17PM -0400, George T. Talbot wrote:
> > One thing that I do in my program, which links to the last snapshot you
> > guys made that wasn't part of GCC, is this:
> > 
> > "socketostream.h"
> 
> Do you recall the "Socket++" library from a few years ago?  If things go
> well, the Boost site will be taking over maintainence in the next few weeks.
> I don't know yet whether we'll do a complete rewrite, or just minor tweaks,
> or what...
> 
> In any case, writing new streambufs and streams to use pipes, sockets,
> whatnot, is an interest of mine.

I'll have to take a look at Socket++.  I didn't find it when I looked
before, but I probably wasn't looking hard enough.  Bummer, because I'd
rather not write such stuff myself.  ;^)

> >         #ifdef WIN32
> >         #error "close() probably isn't right for a socket!"
> >         #endif
> 
> Supporting that platform, though, is going to be a pain...

Yup.  If sockets were handles, then it would be equivalent to *nix,
really.  Would've thought they fixed that when they went from Win16 to
Win32, but I guess not.

> > You guys still support this non-standard filebuf constructor, right? 
> 
> Sorry, exactly which one there is non-standard?  (Without all the private
> members, we couldn't tell what's being called.)

The file I showed you, "socketostream.h" was the complete file.  Here it
is again, for clarity:

 1      template<typename _CharT,
 2              typename _Traits = char_traits<_CharT> >
 3      class basic_socketostream
 4              : public basic_ostream<_CharT, _Traits>
 5      {
 6      public:
 7              basic_socketostream(int iSocket)
 8                      : basic_ostream<_CharT, _Traits>(0),
 9                        m_iSocket(iSocket),
10                        m_fb(iSocket, "socket", ios::out)
11              {
12                      this->init(&m_fb);
13              }
14
15      virtual ~basic_socketostream()
16      {
17              shutdown(m_iSocket, 2);
18
19      #ifdef WIN32
20      #error "close() probably isn't right for a socket!"
21      #endif
22      }
23
24      private:
25              int     m_iSocket;
26              filebuf m_fb;
27      };
28
29      typedef basic_socketostream<char>       socketostream;

If you look at line 26, basic_socketostream "has a" plain, unadulturated
filebuf object.  Looking at line 10, you see that I use the non-standard
constructor for the filebuf:

      // Non-standard ctor:
      basic_filebuf(int __fd, const char* __name = "unknown", 
                    ios_base::openmode __mode = ios_base::in |
ios_base::out);

This comes from line 80 of bits/std_fstream.h in the 2.90.3
distribution.  Will this non-standard constructor remain in the shipping
version?  (Please say yes...;^)  I use the above class in my program to
send output to a socket which I've previously done accept().

(Note:  if you want to use the above in a program, make sure to include
<fstream> and <ostream> before including socketostream.h)

> Dunno about the memory leak problem.

When I run the following test program on my system, using gcc 2.95.2,
and the last separate release of libstdc++-v3, the 2.90.3 release, it
will leak memory until it crashes.  While at first it may appear that
I'm abusing the fstream class, my conjecture is that any failure at
close() in the basic libstdc++ object will leak memory and this was the
best way I could figure to make it happen.  This is on my Linux system,
btw.

Would you happen to have a more recent release of the compiler/libstdc++
on which to try?  I'd do it myself, but I'm a bit constrained here
w.r.t. disk space.  Is there a bug tracking system somewhere where I can
report this?


#include <ostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>

template<typename _CharT, typename _Traits = char_traits<_CharT> >
class basic_fdostream : public basic_ostream<_CharT, _Traits>
{
public:
        basic_fdostream(int iFD)
                : basic_ostream<_CharT, _Traits>(0),
                  m_iFD(iFD),
                  m_fb(iFD, "some fd", ios::out)
        {
                this->init(&m_fb);
        }

        virtual ~basic_fdostream()
        {
                // Force close() to fail when filebuf's destructor runs.
                // If you comment out this line, the program works as
expected.
                close(m_iFD);
        }

private:
        int             m_iFD;
        filebuf m_fb;
};

int     main(int argc, char*argv[])
{
        for (int i=0; i<50000; ++i)
        {
                int     fd      = open("wacko.txt", O_WRONLY | O_CREAT |
O_TRUNC, 0700);

                assert(fd != -1);

                basic_fdostream<char>   duh(fd);

                duh << "Quack" << flush;
        }

        return 0;
}
--
George T. Talbot
<george at moberg dot com>

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