boost 1.40 beta, serialization via base pointer crashes

The following example works on Linux/gcc but crashes on latest AIX v10.1 compiler #include <fstream> #include <assert.h> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/string.hpp> // no need to include <string> #include <boost/serialization/export.hpp> // explicit code for exports (place last) class RepeatBase { public: RepeatBase() {} virtual ~RepeatBase() {} virtual const std::string& name() const = 0; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) {} }; class RepeatDerived : public RepeatBase { public: RepeatDerived( const std::string& name) : name_(name) {} RepeatDerived() {} virtual const std::string& name() const { return name_;} private: std::string name_; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { // save/load base class information ar & boost::serialization::base_object<RepeatBase>(*this); ar & name_; } }; class Defs { public: Defs(const std::string& f) : fileName_(f), repeat_(new RepeatDerived(f)) {} Defs() : repeat_(NULL) {} ~Defs() { delete repeat_;} bool operator==(const Defs& rhs) const { return fileName_ == rhs.fileName_;} const std::string& fileName() const { return fileName_;} private: std::string fileName_; RepeatBase* repeat_; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /*version*/) { ar & fileName_; ar & repeat_; } }; BOOST_CLASS_EXPORT(RepeatBase); BOOST_CLASS_EXPORT(RepeatDerived); BOOST_SERIALIZATION_ASSUME_ABSTRACT(RepeatBase) int main() { // With this explicit cast we get a bit further, but still crashes on AIX // i.e crash on ar.save_pointer(vp, bpos); // // boost::serialization::void_cast_register<RepeatDerived, RepeatBase>(0,0); const Defs saveDefs("saveFile.txt"); { // Save the defs file std::ofstream ofs( saveDefs.fileName().c_str() ); boost::archive::text_oarchive oa( ofs ); oa << saveDefs; } { // Restore the defs file Defs loadDefs; std::ifstream ifs(saveDefs.fileName().c_str()); boost::archive::text_iarchive ia(ifs); ia >> loadDefs; assert( saveDefs == loadDefs ); } return 0; } //========================================================================================= This bug was present in boost 1.39 and is still broken in boost 1.40. The code above shows that base/derived relationship work on one compiler but is _competely_ broken another. Explicitly registering the base/derived relationship just moves the crash to a later point. template<class T> struct polymorphic { static void save( Archive &ar, T & t ){ ...... // convert pointer to more derived type. if this is thrown // it means that the base/derived relationship hasn't be registered vp = serialization::void_downcast( *true_type, *this_type, static_cast<const void *>(&t) ); if(NULL == vp){ boost::serialization::throw_exception( archive_exception(archive_exception::unregistered_cast) //< crash1 here ); } ..... ar.save_pointer(vp, bpos); //< crashe2 here after explicit base/derived registration I thought this bug had been fixed, so I am not sure if this is a regression ? Is there any way I can help, as this is show stopper bug for us. Best regards, Ta, Avi

Is the "latest AIX v10.1 compiler" the same as the IBM VaCPP used in the trunk tests? These tests show that compiler failing a number of tests which use export. This has been traced to the compiler optimizing out code not explicitly referred to. Robert Ramey "Avi Bahra" <avibahra@googlemail.com> wrote in message news:af1b101f0908180614w4893e66cxd949ce8ee0d4f583@mail.gmail.com... The following example works on Linux/gcc but crashes on latest AIX v10.1 compiler #include <fstream> #include <assert.h> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/string.hpp> // no need to include <string> #include <boost/serialization/export.hpp> // explicit code for exports (place last) class RepeatBase { public: RepeatBase() {} virtual ~RepeatBase() {} virtual const std::string& name() const = 0; private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) {} }; class RepeatDerived : public RepeatBase { public: RepeatDerived( const std::string& name) : name_(name) {} RepeatDerived() {} virtual const std::string& name() const { return name_;} private: std::string name_; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { // save/load base class information ar & boost::serialization::base_object<RepeatBase>(*this); ar & name_; } }; class Defs { public: Defs(const std::string& f) : fileName_(f), repeat_(new RepeatDerived(f)) {} Defs() : repeat_(NULL) {} ~Defs() { delete repeat_;} bool operator==(const Defs& rhs) const { return fileName_ == rhs.fileName_;} const std::string& fileName() const { return fileName_;} private: std::string fileName_; RepeatBase* repeat_; friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int /*version*/) { ar & fileName_; ar & repeat_; } }; BOOST_CLASS_EXPORT(RepeatBase); BOOST_CLASS_EXPORT(RepeatDerived); BOOST_SERIALIZATION_ASSUME_ABSTRACT(RepeatBase) int main() { // With this explicit cast we get a bit further, but still crashes on AIX // i.e crash on ar.save_pointer(vp, bpos); // // boost::serialization::void_cast_register<RepeatDerived, RepeatBase>(0,0); const Defs saveDefs("saveFile.txt"); { // Save the defs file std::ofstream ofs( saveDefs.fileName().c_str() ); boost::archive::text_oarchive oa( ofs ); oa << saveDefs; } { // Restore the defs file Defs loadDefs; std::ifstream ifs(saveDefs.fileName().c_str()); boost::archive::text_iarchive ia(ifs); ia >> loadDefs; assert( saveDefs == loadDefs ); } return 0; } //========================================================================================= This bug was present in boost 1.39 and is still broken in boost 1.40. The code above shows that base/derived relationship work on one compiler but is _competely_ broken another. Explicitly registering the base/derived relationship just moves the crash to a later point. template<class T> struct polymorphic { static void save( Archive &ar, T & t ){ ...... // convert pointer to more derived type. if this is thrown // it means that the base/derived relationship hasn't be registered vp = serialization::void_downcast( *true_type, *this_type, static_cast<const void *>(&t) ); if(NULL == vp){ boost::serialization::throw_exception( archive_exception(archive_exception::unregistered_cast) //< crash1 here ); } ..... ar.save_pointer(vp, bpos); //< crashe2 here after explicit base/derived registration I thought this bug had been fixed, so I am not sure if this is a regression ? Is there any way I can help, as this is show stopper bug for us. Best regards, Ta, Avi ------------------------------------------------------------------------------ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (2)
-
Avi Bahra
-
Robert Ramey