Opened 13 years ago

Last modified 13 years ago

#3650 reopened Feature Requests

Text Serialization crashes when istream close unexpectedly

Reported by: Doug Wallas Owned by: Robert Ramey
Milestone: Boost 1.42.0 Component: serialization
Version: Boost Development Trunk Severity: Problem
Keywords: Cc:

Description

I am using TextSerialization over a tcp::iostream. I am retrieving object pointers through the serialization mecanisms.

boost::archive::text_iarchive ia(*_stream); while(!_stream->eof()) {

boost::shared_ptr<Message> msg; ia >> msg; ...

}

If the socket stream close unexpectedly, then the program goes to fault.

It seems that moving the check for stream failure after the data reads in the basic_text_iprimitive.hpp file fixes the problem.

Thanks

Change History (11)

comment:1 by Steven Watanabe, 13 years ago

Component: Noneserialization
Owner: set to Robert Ramey

comment:2 by Robert Ramey, 13 years ago

Hmmm - I'm not sure that is the correct fix.

wouldn't it be better to use something like:

boost::archive::text_iarchive ia(*_stream); while(! _stream->eof() && ! _stream->fail() ) {

boost::shared_ptr<Message> msg; ia >> msg; ...

}

I'm reluctant to add "too much" code in the depths of the library.

Robert Ramey

in reply to:  2 comment:3 by Doug Wallas, 13 years ago

The problem seems to be on the >> operator. The library do read from the stream, but does not check after reading that the stream had not encoutered an error while reading. The >> operator then starts creating a new object from what he just read and sigfaults :(

I may be wrong, but i think the fail() is updated after a read, so the check on _stream->fail() would be ok (the library already does one in internal) and the crash would still occur.

comment:4 by Robert Ramey, 13 years ago

Resolution: wontfix
Status: newclosed
Type: BugsFeature Requests

The reason that I did it the way I did was to permit the user code to handle the fail case. If I throw an exception after each operation, then the user can't make code like

boost::archive::text_iarchive ia(*_stream);
do{
    boost::shared_ptr<Message> msg; 
    ia >> msg; ...
}while(! _stream->eof() && ! _stream->fail() ) {

But would be obligated to write exception handling code. If you really want things to operate this way, you can write

boost::archive::text_iarchive ia(*_stream);
do{
    boost::shared_ptr<Message> msg; 
    ia >> msg; ...
    if(_stream->fail())
        throw ...
}while(! _stream->eof()) {

So the current situation leaves more flexibility to the user.

Robert Ramey

in reply to:  4 comment:5 by anonymous, 13 years ago

Hello, I understand your point but the library sigfaults on the >> operator... So i think it's not possible for the user code to handle it :(

 boost::archive::text_iarchive ia(*_stream);
 do{
     boost::shared_ptr<Message> msg; 
     ia >> msg; // sigfaults
     if(_stream->fail()) // Wont be called
         throw ...
 }while(! _stream->eof()) {

Thanks for your time looking at the problem.

Replying to ramey:

The reason that I did it the way I did was to permit the user code to handle the fail case. If I throw an exception after each operation, then the user can't make code like

boost::archive::text_iarchive ia(*_stream);
do{
    boost::shared_ptr<Message> msg; 
    ia >> msg; ...
}while(! _stream->eof() && ! _stream->fail() ) {

But would be obligated to write exception handling code. If you really want things to operate this way, you can write

boost::archive::text_iarchive ia(*_stream);
do{
    boost::shared_ptr<Message> msg; 
    ia >> msg; ...
    if(_stream->fail())
        throw ...
}while(! _stream->eof()) {

So the current situation leaves more flexibility to the user.

Robert Ramey

comment:6 by anonymous, 13 years ago

Resolution: wontfix
Status: closedreopened
Type: Feature RequestsBugs

I just seen that the type was changed to feature request... The serialization library just crashes i dont think it can be considered as a feature request...

comment:7 by Robert Ramey, 13 years ago

Resolution: wontfix
Status: reopenedclosed
 boost::archive::text_iarchive ia(*_stream);
 do{
     boost::shared_ptr<Message> msg; 
     // check here that the stream is OK. That is, if the stream
     // has been unexpected closed - deal with it here!
     if(_stream->eof() or stream-> ?)
         break;
     ia >> msg; // sigfaults
     if(_stream->fail()) // Wont be called
         throw ...
 }while(! _stream->eof()) {

comment:8 by anonymous, 13 years ago

Resolution: wontfix
Status: closedreopened

It wouldnt work since ">>" is blocking so your checks could be OK, but it would still sigfaults on the ">>" operand as i mentioned before.

If the stream is closed while waiting on the >> operand, a modification of the library is necessary or there's no other way (i could think of) to catch that kind of error.

comment:9 by Robert Ramey, 13 years ago

Resolution: wontfix
Status: reopenedclosed
Type: BugsFeature Requests

The library has to assume that the stream remains open while an archive is being saved. This is not an unreasonable expectation.

basically the best way to handle this would be to trap the situation where the stream closes and not make any serialization library calls when this is detected.

In any case, the library won't be changing.

Robert Ramey

comment:10 by Vladimir Prus, 13 years ago

Resolution: wontfix
Status: closedreopened

Robert, I don't understand your position here. The stream can unexpectedly fail at any moment, and stream do fail in properly written programs. Even if the user checks that stream is OK right before calling operator<<, you can get a stream error -- e.g. a network connection can close immediately after user's check is executed. It does not seem that crashing in face of a natural situation is desirable. Could you clarify further?

Thanks, Volodya

comment:11 by Francois Valette, 13 years ago

Hello, We encounter the same problem sometimes when our stream failed unexpectedly. The occurence is pretty rare so it was hard to find the cause... Thx for pointing out the fix Doug.

Note: See TracTickets for help on using tickets.