Subject: Re: [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-31 06:35:43
#3080: dynamic_cast returns 0 on polymorphic serialization with weak_ptr
----------------------------------------------------+-----------------------
Reporter: Takatoshi Kondo <kondo_at_[hidden]> | Owner: ramey
Type: Bugs | Status: reopened
Milestone: Boost 1.40.0 | Component: serialization
Version: Boost 1.39.0 | Severity: Problem
Resolution: | Keywords:
----------------------------------------------------+-----------------------
Changes (by Takatoshi Kondo <kondo_at_[hidden]>):
* status: closed => reopened
* resolution: worksforme =>
Comment:
== Result of test_zmisc.cpp ==
=== On VC++ 9.0.21022.8 RTM ===
Compile successed.
Run failed. Access violation occured. pb2_1 is incorrect.
=== On g++ (Gentoo 4.3.2-r3 p1.6, pie-10.1.5) 4.3.2. ===
Compile successed.
Run failed. Access violation occured. pb2_1 is incorrect.
----
Same result.
I think that these compilers are comparatively new, and major.
Could you check your sample and my sample using these compiler?
== My analysis ==
pb2(original data)'s !__vfptr point to vftable for Base2.
pb2_1(deserialized)'s !__vfptr point to vftavble for Base1.
pb2_1's !__vfptr should point to vftable for Base2.
Why does pb2_1's !__vfptr point to vftable for Base1.
The reseason is following...
{{{
#!cpp
template<class T>
void reset(shared_ptr<T> & s, T * r){
if(NULL == r){
s.reset();
return;
}
// get pointer to the most derived object. This is effectively
// the object identifer
const void * od = object_identifier(r);
if(NULL == m_pointers)
m_pointers = new collection_type;
iterator_type it = m_pointers->find(od);
if(it == m_pointers->end()){
s.reset(r);
m_pointers->insert(collection_type::value_type(od,s)); //
point1
}
else{
s = static_pointer_cast<T>((*it).second); // point2
}
}
}}}
https://svn.boost.org/trac/boost/browser/tags/release/Boost_1_39_0/boost/archive/shared_ptr_helper.hpp
1. When m_wp deserialize, program passed point1.
2. When pb2_1 deserialize, program passed point2.Because they point to
same object.
After step1, type information was lost. Because the container m_pointers
type is shared_ptr<void>.
In step2, it is impossible to distinguish that (*it).second is instance of
'Sub' or instance of 'Base2'.
Currently, member function reset() considers (*it).second to
shared_ptr<Base2>, based on type T.
Unfortunately the real object type is 'Sub'.
After all, writing position for the desirializing data was shifted. And
pb2_1 was broken.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3080#comment:8> 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