Subject: [Boost-bugs] [Boost C++ Libraries] #3080: dynamic_cast returns 0 on polymorphic serialization with weak_ptr
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-05-25 13:26:35
#3080: dynamic_cast returns 0 on polymorphic serialization with weak_ptr
---------------------------------------------------+------------------------
Reporter: Takatoshi Kondo <kondo_at_[hidden]> | Owner: ramey
Type: Bugs | Status: new
Milestone: Boost 1.40.0 | Component: serialization
Version: Boost 1.39.0 | Severity: Problem
Keywords: |
---------------------------------------------------+------------------------
=== 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).
{{{
#!cpp
// 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.
{{{
#!cpp
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}
}}}
=== Environment ===
g++ (Gentoo 4.3.2-r3 p1.6, pie-10.1.5) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3080> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:00 UTC