Opened 13 years ago

Closed 13 years ago

Last modified 13 years ago

#3079 closed Bugs (duplicate)

dynamic_cast returns 0 on polymorphic serialization with weak_ptr

Reported by: Takatoshi Kondo <kondo@…> Owned by:
Milestone: Boost 1.40.0 Component: None
Version: Boost 1.38.0 Severity: Problem
Keywords: Cc:

Description

Problem

In multiple inheritance case, after de-serialization, failed to dynamic_cast from a data member polymorphic serialize via 2nd base class (Left) to subclass (Bottom).

        // check
        Left *pLeft = h2.mbl_.get();
        Bottom *pBottomFromLeft = dynamic_cast<Bottom *>(pLeft);

        Right *pRight = h2.mbr_.get();
        Bottom *pBottomFromRight = dynamic_cast<Bottom *>(pRight);

        assert(pBottomFromLeft);  // Success
        assert(pBottomFromRight); // Fail. Comment out *1 and *2, it works corrctly.

My analysis

Class 'Bottom' has weak_ptr that point to itself. When weak_ptr member wp_ exclude serialization, dynamic_cast is success.(Comment out *1 and *2 lines.)

I set break point (using gdb). => is position.

class Holder {
public:
    LeftSp mbl_;  // shared_ptr<Left>
    RightSp mbr_; // shared_ptr<Right>

    Holder() {} // for serialize
    Holder(BottomSp l, BottomSp r):mbl_(l) ,mbr_(r) {} // for appli construct

    // serialize
    friend class boost::serialization::access;
    template<class Archive>
    void save(Archive &ar, const unsigned int /* file_version */) const
    {
        // polymophic serialize via shared_ptr
        ar << BOOST_SERIALIZATION_NVP(mbl_);
        // polymophic serialize via shared_ptr
        ar << BOOST_SERIALIZATION_NVP(mbr_);
    }
    template<class Archive>
    void load(Archive & ar, const unsigned int /* file_version */)
    {
        // polymophic de-serialize via shared_ptr
        ar >> BOOST_SERIALIZATION_NVP(mbl_);
        // polymophic de-serialize via shared_ptr
        ar >> BOOST_SERIALIZATION_NVP(mbr_);
=>  }
    BOOST_SERIALIZATION_SPLIT_MEMBER()
};

And, I printed below values.

In assertion failed case, _vptr.Left is equal to _vptr.Right.

(gdb) p *mbl_.px
$1 = {_vptr.Left = 0x8060ba8}
(gdb) p *mbr_.px
$1 = {_vptr.Right = 0x8060ba8}

But, success case (remove the member wp_'s serialization), _vptr.Left is not equal to _vptr.Right

(gdb) p *mbl_.px
$1 = {_vptr.Left = 0x805d1e8}
(gdb) p *mbr_.px
$1 = {_vptr.Right = 0x805d1f8}

Change History (2)

comment:1 by Takatoshi Kondo <kondo@…>, 13 years ago

Resolution: duplicate
Status: newclosed

I'm sorry. The operation has been mistaken. Please integrate this ticket into #3800.

comment:2 by Takatoshi Kondo <kondo@…>, 13 years ago

Note: See TracTickets for help on using tickets.