Boost logo

Boost Users :

Subject: Re: [Boost-users] boost 1.40 beta, serialization via base pointer crashes
From: Robert Ramey (ramey_at_[hidden])
Date: 2009-08-18 12:58:13


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_at_[hidden]> wrote in message news:af1b101f0908180614w4893e66cxd949ce8ee0d4f583_at_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_at_[hidden]
  http://lists.boost.org/mailman/listinfo.cgi/boost-users



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net