Opened 9 years ago

Closed 9 years ago

#9370 closed Bugs (invalid)

segmentation fault with serialization

Reported by: florian.seidel@… Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.49.0 Severity: Showstopper
Keywords: Cc:

Description

The following minimal program crashes in Boost 1.49.0

#include <iostream>
#include <string>
#include <sstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/base_object.hpp>
class A {
public:
        A() { }
        virtual ~A() { }
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version) {

        }
};


class C : public A { };

class B : public A {
public:
        B() {
        }
        template<class Archive>
        void serialize(Archive & ar, const unsigned int version) {
                ar & boost::serialization::base_object<A>(*this);
        }
};


BOOST_CLASS_VERSION(A,1)
BOOST_CLASS_VERSION(B,2)
BOOST_CLASS_VERSION(C,3)

int main() {
        using namespace std;
        cout << "Start boost-serialization test\n\n";

        boost::shared_ptr<A> p1( new B );
        boost::shared_ptr<A> p2;

        ostringstream os(ios_base::out|ios_base::binary);
        {
                boost::archive::binary_oarchive oar(os);

                oar.register_type((C*)0);
                oar.register_type((B*)0);

                oar & p1;
        }
        const string data(os.str());

        cout << "Serialization done, data size [bytes]: " << data.size() << endl;

        istringstream is(data, ios_base::in|ios_base::binary);
        {
                boost::archive::binary_iarchive iar(is);
                iar.register_type((B*)0);
                iar & p2;
        }

        cout << "Deserialization done\n";

        return 0;
}

Thread 1 (Thread 0x7ffff7fcc740 (LWP 3383)):
#0  0x00007ffff7ba9c3a in boost::archive::detail::basic_iarchive_impl::load_pointer(boost::archive::detail::basic_iarchive&, void*&, boost::archive::detail::basic_pointer_iserializer const*, boost::archive::detail::basic_pointer_iserializer const* (*)(boost::serialization::extended_type_info const&)) () from /usr/lib64/libboost_serialization.so.1.49.0
No symbol table info available.
#1  0x0000000000448b31 in boost::archive::detail::load_pointer_type<boost::archive::binary_iarchive>::invoke<A*> (ar=..., t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>) at /usr/include/boost/archive/detail/iserializer.hpp:524
        bpis_ptr = 0x664d90
        newbpis_ptr = 0x7ffff7fd0000
#2  0x0000000000448a11 in boost::archive::load<boost::archive::binary_iarchive, A*> (ar=..., t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>) at /usr/include/boost/archive/detail/iserializer.hpp:592
No locals.
#3  0x0000000000448964 in boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::load_override<A*> (this=0x7fffffffd4d0, t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>) at /usr/include/boost/archive/detail/common_iarchive.hpp:66
No locals.
#4  0x00000000004488a9 in boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override<A*> (this=0x7fffffffd4d0, t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>, version=0) at /usr/include/boost/archive/basic_binary_iarchive.hpp:70
No locals.
#5  0x00000000004487d3 in boost::archive::binary_iarchive_impl<boost::archive::binary_iarchive, char, std::char_traits<char> >::load_override<A*> (this=0x7fffffffd4d0, t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>) at /usr/include/boost/archive/binary_iarchive_impl.hpp:50
No locals.
#6  0x00000000004486de in boost::archive::detail::interface_iarchive<boost::archive::binary_iarchive>::operator>><A*> (this=0x7fffffffd4d0, t=@0x7fffffffd158: 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>) at /usr/include/boost/archive/detail/interface_iarchive.hpp:60
No locals.
#7  0x00000000004485df in boost::serialization::nvp<A*>::load<boost::archive::binary_iarchive> (this=0x7fffffffd190, ar=...) at /usr/include/boost/serialization/nvp.hpp:87
No locals.
#8  0x000000000044850e in boost::serialization::access::member_load<boost::archive::binary_iarchive, boost::serialization::nvp<A*> > (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/access.hpp:101
No locals.
#9  0x0000000000448266 in boost::serialization::detail::member_loader<boost::archive::binary_iarchive, boost::serialization::nvp<A*> >::invoke (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/split_member.hpp:54
No locals.
#10 0x00000000004480e3 in boost::serialization::split_member<boost::archive::binary_iarchive, boost::serialization::nvp<A*> > (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/split_member.hpp:69
No locals.
#11 0x000000000044802b in boost::serialization::nvp<A*>::serialize<boost::archive::binary_iarchive> (this=0x7fffffffd190, ar=..., file_version=0) at /usr/include/boost/serialization/nvp.hpp:89
No locals.
#12 0x0000000000447de1 in boost::serialization::access::serialize<boost::archive::binary_iarchive, boost::serialization::nvp<A*> > (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/access.hpp:118
No locals.
#13 0x0000000000447b8e in boost::serialization::serialize<boost::archive::binary_iarchive, boost::serialization::nvp<A*> > (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/serialization.hpp:69
No locals.
#14 0x0000000000447a08 in boost::serialization::serialize_adl<boost::archive::binary_iarchive, boost::serialization::nvp<A*> > (ar=..., t=..., file_version=0) at /usr/include/boost/serialization/serialization.hpp:128
        v = {<boost::totally_ordered1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >> = {<boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::less_than_comparable2<boost::serialization::version_type, unsigned int, boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::detail::empty_base<boost::serialization::version_type>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, t = 0}
#15 0x000000000044784a in boost::archive::detail::load_non_pointer_type<boost::archive::binary_iarchive>::load_only::invoke<boost::serialization::nvp<A*> > (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:373
No locals.
#16 0x0000000000447369 in boost::archive::detail::load_non_pointer_type<boost::archive::binary_iarchive>::invoke<boost::serialization::nvp<A*> const> (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:439
No locals.
#17 0x0000000000446d51 in boost::archive::load<boost::archive::binary_iarchive, boost::serialization::nvp<A*> const> (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:592
No locals.
#18 0x0000000000446628 in boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::load_override<boost::serialization::nvp<A*> const> (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/detail/common_iarchive.hpp:66
No locals.
#19 0x0000000000445f41 in boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override<boost::serialization::nvp<A*> const> (this=0x7fffffffd4d0, t=..., version=0) at /usr/include/boost/archive/basic_binary_iarchive.hpp:70
No locals.
#20 0x000000000044575d in boost::archive::binary_iarchive_impl<boost::archive::binary_iarchive, char, std::char_traits<char> >::load_override<boost::serialization::nvp<A*> const> (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/binary_iarchive_impl.hpp:50
No locals.
#21 0x0000000000444f38 in boost::archive::detail::interface_iarchive<boost::archive::binary_iarchive>::operator>><boost::serialization::nvp<A*> const> (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/detail/interface_iarchive.hpp:60
No locals.
#22 0x0000000000444bba in boost::serialization::load<boost::archive::binary_iarchive, A> (ar=..., t=..., file_version=1) at /usr/include/boost/serialization/shared_ptr.hpp:137
        r = 0x4403a6 <boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >::less_than_comparable1()+24>
#23 0x000000000044471a in boost::serialization::free_loader<boost::archive::binary_iarchive, boost::shared_ptr<A> >::invoke (ar=..., t=..., file_version=1) at /usr/include/boost/serialization/split_free.hpp:58
        v = {<boost::totally_ordered1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >> = {<boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::less_than_comparable2<boost::serialization::version_type, unsigned int, boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::detail::empty_base<boost::serialization::version_type>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, t = 1}
#24 0x00000000004444bb in boost::serialization::split_free<boost::archive::binary_iarchive, boost::shared_ptr<A> > (ar=..., t=..., file_version=1) at /usr/include/boost/serialization/split_free.hpp:74
No locals.
#25 0x0000000000444355 in boost::serialization::serialize<boost::archive::binary_iarchive, A> (ar=..., t=..., file_version=1) at /usr/include/boost/serialization/shared_ptr.hpp:171
No locals.
#26 0x0000000000443fcc in boost::serialization::serialize_adl<boost::archive::binary_iarchive, boost::shared_ptr<A> > (ar=..., t=..., file_version=1) at /usr/include/boost/serialization/serialization.hpp:128
        v = {<boost::totally_ordered1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::less_than_comparable1<boost::serialization::version_type, boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > > >> = {<boost::equality_comparable1<boost::serialization::version_type, boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::totally_ordered2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::less_than_comparable2<boost::serialization::version_type, unsigned int, boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> > >> = {<boost::equality_comparable2<boost::serialization::version_type, unsigned int, boost::detail::empty_base<boost::serialization::version_type> >> = {<boost::detail::empty_base<boost::serialization::version_type>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, t = 1}
#27 0x0000000000443bd5 in boost::archive::detail::iserializer<boost::archive::binary_iarchive, boost::shared_ptr<A> >::load_object_data (this=0x664ea0, ar=..., x=0x7fffffffd7f0, file_version=1) at /usr/include/boost/archive/detail/iserializer.hpp:188
No locals.
#28 0x00007ffff7ba90ae in boost::archive::detail::basic_iarchive::load_object(void*, boost::archive::detail::basic_iserializer const&) () from /usr/lib64/libboost_serialization.so.1.49.0
No symbol table info available.
#29 0x00000000004439f4 in boost::archive::detail::load_non_pointer_type<boost::archive::binary_iarchive>::load_standard::invoke<boost::shared_ptr<A> > (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:387
        x = 0x7fffffffd7f0
#30 0x0000000000443856 in boost::archive::detail::load_non_pointer_type<boost::archive::binary_iarchive>::invoke<boost::shared_ptr<A> > (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:439
No locals.
#31 0x0000000000442fbe in boost::archive::load<boost::archive::binary_iarchive, boost::shared_ptr<A> > (ar=..., t=...) at /usr/include/boost/archive/detail/iserializer.hpp:592
No locals.
#32 0x00000000004428f2 in boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>::load_override<boost::shared_ptr<A> > (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/detail/common_iarchive.hpp:66
No locals.
#33 0x0000000000442597 in boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>::load_override<boost::shared_ptr<A> > (this=0x7fffffffd4d0, t=..., version=0) at /usr/include/boost/archive/basic_binary_iarchive.hpp:70
No locals.
#34 0x0000000000441e75 in boost::archive::binary_iarchive_impl<boost::archive::binary_iarchive, char, std::char_traits<char> >::load_override<boost::shared_ptr<A> > (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/binary_iarchive_impl.hpp:50
No locals.
#35 0x0000000000441734 in boost::archive::detail::interface_iarchive<boost::archive::binary_iarchive>::operator>><boost::shared_ptr<A> > (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/detail/interface_iarchive.hpp:60
No locals.
#36 0x00000000004412a3 in boost::archive::detail::interface_iarchive<boost::archive::binary_iarchive>::operator&<boost::shared_ptr<A> > (this=0x7fffffffd4d0, t=...) at /usr/include/boost/archive/detail/interface_iarchive.hpp:67
No locals.
#37 0x000000000043fb6f in main () at /import/home2/seidel/test/BoostSerialize/main.cpp:61
        iar = {<boost::archive::binary_iarchive_impl<boost::archive::binary_iarchive, char, std::char_traits<char> >> = {<boost::archive::basic_binary_iprimitive<boost::archive::binary_iarchive, char, std::char_traits<char> >> = {m_sb = @0x7fffffffd680, archive_locale = {px = 0x665740}, locale_saver = {<boost::noncopyable_::noncopyable> = {<No data fields>}, s_save_ = @0x7fffffffd680, a_save_ = {static none = 0, static ctype = 1, static numeric = 2, static collate = 4, static time = 8, static monetary = 16, static messages = 32, static all = 63, _M_impl = 0x7ffff7b5caa0, static _S_classic = <optimized out>, static _S_global = <optimized out>, static _S_categories = <optimized out>, static _S_once = <optimized out>}}}, <boost::archive::basic_binary_iarchive<boost::archive::binary_iarchive>> = {<boost::archive::detail::common_iarchive<boost::archive::binary_iarchive>> = {<boost::archive::detail::basic_iarchive> = {<No data fields>}, <boost::archive::detail::interface_iarchive<boost::archive::binary_iarchive>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <boost::archive::detail::shared_ptr_helper> = {m_pointers = 0x0, m_pointers_132 = 0x0}, <No data fields>}
        p2 = {px = 0x0, pn = {pi_ = 0x0}}
        os = <incomplete type>
        data = "\026\000\000\000\000\000\000\000serialization::archive\t\000\004\b\004\b\001\000\000\000\000\001\000\000\000\001\000\001\002\000\000\000\000\000\000\000\001\001\000\000\000\001\000\000"
        is = <incomplete type>
        p1 = {px = 0x665700, pn = {pi_ = 0x665720}}

Change History (4)

comment:1 by viboes, 9 years ago

Component: Noneserialization
Owner: set to Robert Ramey

comment:2 by Robert Ramey, 9 years ago

I'm guessing that this problem is due to the fact that we're reading the string before it's closed. Try the following:

{
        ostringstream os(ios_base::out|ios_base::binary);
        {
                boost::archive::binary_oarchive oar(os);

                oar.register_type((C*)0);
                oar.register_type((B*)0);

                oar & p1;
        }
        const string data(os.str());

        cout << "Serialization done, data size [bytes]: " << data.size() << endl;
} // closes file os
{
        istringstream is(data, ios_base::in|ios_base::binary);
        {
                boost::archive::binary_iarchive iar(is);
                iar.register_type((B*)0);
                iar & p2;
        }

        cout << "Deserialization done\n";
}

comment:3 by florian.seidel@…, 9 years ago

Actually, the problem is caused by not registering classes in the same order in the output archive as in the input archive. Ticket can be closed. It would be nice to have this requirement statet clearly in the documentation, maybe in bold font.

comment:4 by Robert Ramey, 9 years ago

Resolution: invalid
Status: newclosed
Note: See TracTickets for help on using tickets.