Boost logo

Boost :

Subject: Re: [boost] [serialization] basic_text_iprimitive destructor throws
From: Robert Ramey (ramey_at_[hidden])
Date: 2008-11-09 19:17:36


When I looked into this, I was surprised that stream threw exception.
It seems that it depends on which standard library is being used
so I don't think that std::failure exists in all standard libraries.

I would guess that one would want to ignore all
exceptions at this poing.

Robert Ramey

John Salmon wrote:
> Here's a two-line patch (not counting the comment). This patch
> simply ignores any ios_base::failure excpetions from is.sync().
> There are certainly other possibilities, but I don't see any good
> reason to prefer, e.g., checking the result of
> std::uncaught_exception() first or to broaden the
> class of caught exceptions.
>
> John
>
> P.S. I've changed the subject to adhere to conventions.
>
> salmonj_at_drdblogin6.en.desres$ diff -u
> boost/archive/impl/basic_text_iprimitive.ipp.orig
> boost/archive/impl/basic_text_iprimitive.ipp
> --- boost/archive/impl/basic_text_iprimitive.ipp.orig 2008-11-09
> 16:32:30.003405292 -0500
> +++ boost/archive/impl/basic_text_iprimitive.ipp 2008-11-09
> 16:38:51.755281718 -0500
> @@ -147,7 +147,17 @@
> template<class IStream>
> BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
> basic_text_iprimitive<IStream>::~basic_text_iprimitive(){
> - is.sync();
> + try{
> + is.sync();
> + }catch(std::ios_base::failure& e){
> + // is.sync might throw ios_base::failure if an error
> + // occurs and 'is' has the badbit exception
> + // mask set. Should this exception be allowed to "leak out"
> + // of this destructor:
> + // a) never?
> + // b) only if std::uncaught_exception() is false?
> + // c) under some other set of circumstances?
> + }
> }
>
> } // namespace archive
> salmonj_at_drdblogin6.en.desres$
>
>
> On Tue, Nov 4, 2008 at 4:17 PM, John Salmon <john_at_[hidden]>
> wrote:
>> I tried turning on exceptions on the input stream that I use for a
>> text_iarchive, hoping to catch user-level errors such as an attempt
>> to
>> treat a non-archive file as an archive. It seems that when
>> exceptions
>> are enabled on the underlying stream, the basic_text_iprimitive
>> destructor throws a second(?) basic_ios::failure exception, during
>> stack unwinding, which lands me unhappily in the terminate handler.
>>
>> Can the basic_text_iprimitive destructor be protected against
>> accidentally throwing?
>>
>> Here's an demonstration. This is on a Linux system with gcc/4.1.2.
>>
>> John Salmon
>>
>> salmonj_at_drdblogin6.en.desres$ cat ser.cpp
>> #include <boost/archive/text_iarchive.hpp>
>> #include <boost/serialization/serialization.hpp>
>> #include <stdexcept>
>>
>> #include <fstream>
>>
>> struct Foo{
>> int i, j;
>> private:
>> friend class boost::serialization::access;
>> template <class Archive>
>> void serialize(Archive & ar, const unsigned int version)
>> {
>> ar & i & j;
>> }
>> };
>>
>> int main(){
>> Foo foo;
>> std::ifstream ifs("/dev/null");
>> ifs.exceptions(std::istream::failbit | std::istream::badbit);
>>
>> try{
>> boost::archive::text_iarchive tia(ifs);
>> tia >> foo;
>> }catch(std::ios_base::failure &e){
>> std::cerr << "Caught std::ios_base::failure. What: " <<
>> e.what() << "\n";
>> }catch(std::exception &e){
>> std::cerr << "Caught exception. What: " << e.what() << "\n";
>> }
>>
>> return 0;
>> }
>>
>> salmonj_at_drdblogin6.en.desres$ xmk
>> g++ -I/proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/include
>> -g -L/proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/lib
>> -Wl,-rpath,/proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/lib
>> ser.cpp -lboost_serialization -o ser
>> salmonj_at_drdblogin6.en.desres$ ser
>> terminate called after throwing an instance of
>> 'std::ios_base::failure' what(): basic_ios::clear
>> Aborted (core dumped)
>> salmonj_at_drdblogin6.en.desres$ gdb -c
>> drdblogin6.en.desres.deshaw.com-6718.core ser
>> GNU gdb 6.8
>> Copyright (C) 2008 Free Software Foundation, Inc.
>> License GPLv3+: GNU GPL version 3 or later
>> <http://gnu.org/licenses/gpl.html>
>> This is free software: you are free to change and redistribute it.
>> There is NO WARRANTY, to the extent permitted by law. Type "show
>> copying"
>> and "show warranty" for details.
>> This GDB was configured as "x86_64-unknown-linux-gnu"...
>> Reading symbols from
>> /proj/desrad-c/root/Linux/x86_64/boost/1_37_0-13/Release/lib/libboost_serialization.so...done.
>> Loaded symbols for
>> /proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/lib/libboost_serialization.so
>> Reading symbols from
>> /proj/desrad-c/root/Linux/x86_64/gcc/4.1.2-10/lib64/libstdc++.so.6...done.
>> Loaded symbols for
>> /proj/desres/root/Linux/x86_64/gcc/4.1.2-10/lib64/libstdc++.so.6
>> Reading symbols from /lib64/tls/libm.so.6...done.
>> Loaded symbols for /lib64/tls/libm.so.6
>> Reading symbols from
>> /proj/desrad-c/root/Linux/x86_64/gcc/4.1.2-10/lib64/libgcc_s.so.1...done.
>> Loaded symbols for
>> /proj/desres/root/Linux/x86_64/gcc/4.1.2-10/lib64/libgcc_s.so.1
>> Reading symbols from /lib64/tls/libc.so.6...done.
>> Loaded symbols for /lib64/tls/libc.so.6
>> Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
>> Loaded symbols for /lib64/ld-linux-x86-64.so.2
>> Core was generated by `ser'.
>> Program terminated with signal 6, Aborted.
>> [New process 6718]
>> #0 0x0000003f72a2e25d in raise () from /lib64/tls/libc.so.6
>> (gdb) where
>> #0 0x0000003f72a2e25d in raise () from /lib64/tls/libc.so.6
>> #1 0x0000003f72a2fa5e in abort () from /lib64/tls/libc.so.6
>> #2 0x00002b5ab82f5f84 in __gnu_cxx::__verbose_terminate_handler ()
>> at
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/libstdc++-v3/libsupc++/vterminate.cc:97
>> #3 0x00002b5ab82f4106 in __cxxabiv1::__terminate
>> (handler=0x1a3e) at
>>
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/libstdc++-v3/libsupc++/eh_terminate.cc:43
>> #4 0x00002b5ab82f350b in __cxa_call_terminate
>> (ue_header=0x50b730) at
>>
>>
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/libstdc++-v3/libsupc++/eh_call.cc:60
>> #5 0x00002b5ab82f3fa7 in __gxx_personality_v0 ( version=<value
>> optimized out>, actions=6, exception_class=<value optimized out>,
>> ue_header=0x50b730, context=0x7ffff29e5610) at
>>
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/libstdc++-v3/libsupc++/eh_personality.cc:637
>> #6 0x00002b5ab846a068 in _Unwind_RaiseException_Phase2
>> (exc=0x50b730, context=0x7ffff29e5610) at
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/gcc/unwind.inc:66
>> #7 0x00002b5ab846a2db in _Unwind_Resume (exc=0x50b730) at
>> /state/partition1/tmp/tmpXcQw4O/gcc-4.1.2-10/gcc-4.1.2/gcc/unwind.inc:234
>> #8 0x00002b5ab80fd790 in
>> boost::archive::basic_text_iprimitive<std::istream>::~basic_text_iprimitive
>> ()
>> from
>> /proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/lib/libboost_serialization.so
>> #9 0x00002b5ab8109e0c in
>> boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::text_iarchive_impl
>> () from
>> /proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/lib/libboost_serialization.so
>> #10 0x00000000004045ab in text_iarchive (this=0x7ffff29e5ae0,
>> is=@0x7ffff29e58d0, flags=0) at
>> /proj/desres/root/Linux/x86_64/boost/1_37_0-13/Release/include/boost/archive/text_iarchive.hpp:110
>> #11 0x0000000000402c84 in main () at ser.cpp:24 (gdb) quit
>> salmonj_at_drdblogin6.en.desres$
>>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk