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 , 13 years ago
Component: | None → serialization |
---|---|
Owner: | set to |
follow-up: 3 comment:2 by , 13 years ago
comment:3 by , 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.
follow-up: 5 comment:4 by , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Type: | Bugs → Feature 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
comment:5 by , 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 , 13 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Type: | Feature Requests → Bugs |
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 , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
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 , 13 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
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 , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
Type: | Bugs → Feature 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 , 13 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
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 , 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.
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() ) {
}
I'm reluctant to add "too much" code in the depths of the library.
Robert Ramey