This is the mail archive of the gcc@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]

Re: strstream.h (deprecated) is broken


Joe Buck wrote:

>>>gcc version 3.2 20020530 (experimental)
>>>
>>>$ g++ -Wno-deprecated t.cpp
>>>$ ./a.out
>>>Segmentation fault (core dumped)
>>>$ cat t.cpp
>>>#include <strstream.h>
>>>#include <iostream>
>>>
>>>int main()
>>>{
>>>   strstream s;
>>>   for (unsigned i=0 ; i!= 8 ; ++i)
>>>      s << i << std::endl;
>>>   s << std::ends;
>>>
>>>   return 0;
>>>}
>>>      
>>>
>
>By the way, I can't duplicate the crash with 20020529 on Solaris.
>What platform did you use?
>
Hi.

I could reproduce the problem on i686-pc-linux-gnu.
I'm currently testing the following simple patch, which seems to work 
well for me (the testcase runs ok indeed):

*** strstream.cc.~1.9.~ Wed May 15 15:15:17 2002
--- strstream.cc        Fri May 31 23:34:00 2002
*************** strstreambuf::strstreambuf(const unsigne
*** 139,151 ****
  strstreambuf::~strstreambuf()
  {
    if (_M_dynamic && !_M_frozen)
-     {
-       char* p = this->eback();
-       _M_free(p);
-       if (p == _M_buf)
-       _M_buf = 0;
-     }
-   if (_M_buf)
      _M_free(_M_buf);
  }

--- 139,144 ----

The rationale is the following:
1- For strstream the allocated buffer must be freed only when _M_dynamic 
&& !_M_frozen, not otherwise.
2- The beginning of the low level buffer is given, in general, that is 
at any time, by _M_buf, *not* by eback(), which may be != _M_buf if 
there are chars in the putback area.
3- Therefore a single _M_free(_M_buf) - i.e., the dual of the _M_buf = 
_M_alloc(_M_buf_size); performed at construction time - should be ok.
4- Note1: it is not necessary to explicitly make sure that _M_buf != 
NULL since the implementation of _M_free does this for us.
5- Note2: 2 + 3 would explain pretty well why we are currently crashing: 
when the putback area is non-empty eback() != _M_buf, therefore 
additionally to _M_free(p) we carry out also _M_free(_M_buf) thus 
freeing part of the memory two times.

Could you please test/comment on the simple patch above?

Ciao,
Paolo.


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