[PATCH] PR libstdc++/81395 fix crash when write follows large read

Paolo Carlini paolo.carlini@oracle.com
Wed Jul 19 18:15:00 GMT 2017


Hi,

On 19/07/2017 02:17, Jonathan Wakely wrote:
> This fixes a crash that happens in std::filebuf when a large read
> consumes the entire get area and is followed by a write, which is then
> synced to the file by a call to overflow.
>
> The problem is that xsgetn calls _M_set_buffer(0) after reading from
> the file (i.e. when in 'read' mode). As the comments on _M_set_buffer
> say, an argument of 0 is used for 'write' mode. This causes the
> filebuf to have an active put area while in 'read' mode, so that the
> next write inserts straight into that put area, rather than performing
> the required seek to leave 'read' mode.
>
> The next overflow then tries to leave 'read' mode by doing a seek, but
> that then tries to flush the non-empty put area by calling overflow,
> which goes into a loop until we overflow the stack.
>
> The solution is to simply remove the call to _M_set_buffer(0). It's
> not needed because the buffers are already set up appropriately after
> xsgetn has read from the file: there's no active putback, no put area,
> and setg(eback(), egptr(), egptr()) has been called so there's nothing
> available in the get area. All we need to do is set _M_reading = true
> so that a following write knows it needs to perform a seek.
>
> The new testcase passes with GCC 4.5, so this is technically a
> regression. However, I have a more demanding test that fails even with
> GCC 4.5, so I don't think mixing reads and writes without intervening
> seeks was ever working completely. I hope it is now.
Excellent work on this, thanks Jon. Time permitting, I mean to 
investigate a bit more your last interesting observation: I suspected 
that the crazy _M_set_buffer (0) call or the idea itself of calling 
_M_set_buffer in this case, was coming somehow from previous 
incarnations of the buffer, which was already "suboptimal" in this 
respect and didn't make progress... until today ;)

Paolo.



More information about the Libstdc++ mailing list