Subject: [Boost-bugs] [Boost C++ Libraries] #3604: Access violation on diamond inheritance
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-11-10 12:42:10
#3604: Access violation on diamond inheritance
---------------------------------+------------------------------------------
Reporter: kondo@⦠| Owner: ramey
Type: Bugs | Status: new
Milestone: Boost 1.41.0 | Component: serialization
Version: Boost 1.40.0 | Severity: Problem
Keywords: |
---------------------------------+------------------------------------------
= phenomenon =
When I serialize the sub-class via virtual base class,
some BOOST_CLASS_EXPORT order makes access violation.
main.cpp(attached file) reproduce these behavior on VC++ ver 9. Please
check it.
Classes structure is structure.png(attached file).
If BOOST_CLASS_EXPORT order is Target, Sub1, the error doesn't occur.
If BOOST_CLASS_EXPORT order is Sub1, Target, the error occurs.
main.cpp
{{{
#!cpp
#if 0
// OK
BOOST_CLASS_EXPORT(Target)
BOOST_CLASS_EXPORT(Sub1)
#else
// NG
BOOST_CLASS_EXPORT(Sub1)
BOOST_CLASS_EXPORT(Target)
#endif
}}}
= analysis =
I checked the behavior of void_caster::recursive_register step by step.
boost_1_40_0\libs\serialization\src\void_cast.cpp
{{{
#!cpp
// implementation of void caster base class
BOOST_SERIALIZATION_DECL(void)
void_caster::recursive_register(bool includes_virtual_base) const {
void_cast_detail::set_type & s
= void_cast_detail::void_caster_registry::get_mutable_instance();
s.insert(this);
// generate all implied void_casts.
void_cast_detail::set_type::const_iterator it;
for(it = s.begin(); it != s.end(); ++it){
if(* m_derived == * (*it)->m_base)
new void_caster_shortcut( // match A
(*it)->m_derived,
m_base,
m_difference + (*it)->m_difference,
includes_virtual_base
);
if(* (*it)->m_derived == * m_base)
new void_caster_shortcut( // match B
m_derived,
(*it)->m_base,
m_difference + (*it)->m_difference,
includes_virtual_base
);
}
}}}
----
OK Case
r-level means recursive level(not so important).
'No' means registration order(not internal order of container set).
||No||r-level||virtual base||Derived||Base||Action||!OverWrite||
||0||||false||Target||Sub2||-||||
||1||||false||Sub1||Mid1||-||||
||2||||false||Sub1||Mid2||-||||
||3||||false||Sub2||Mid1||match A Sub2 No.0,add No.4||||
||4||1||false||Target||Mid1||-||||
||5||||false||Sub2||Mid2||match A Sub2 No.0,add No.6||||
||6||1||false||Target||Mid2||-||||
||7||||true||Mid1||VBase||match A Mid1 No.1,add No.8||||
||||||||||||match A Mid1 No.3 add No.9||||
||||||||||||match A Mid1 No.4 add No.11||||
||8||1||true||Sub1||VBase||-||||
||9||1||true||Sub2||VBase||match A Sub2 No.0,add No.10||||
||10||2||true||Target||VBase||-||||
||11||2||true||Target||VBase||-||No.10||
||12||||true||Mid2||VBase||match A Mid2 No.2,add No.13||||
||||||||||||match A Mid2 No.5,add No.14||||
||||||||||||match A Mid2 No.6,add No.16||||
||13||1||true||Sub1||Vbase||-||No.8||
||14||1||true||Sub2||VBase||match A Sub2 No.0,add No.15||No.9||
||15||2||true||Target||VBase||-||No.10||
||16||1||true||Target||VBase||-||No.10||
Result (focus on m_includes_virtual_base)
values of s
{{{
#!cpp
void_cast_detail::set_type & s
= void_cast_detail::void_caster_registry::get_mutable_instance();
}}}
{{{
[0] 0x004add48 t const
boost::serialization::void_cast_detail::void_caster *
[1] 0x004add7c t const
boost::serialization::void_cast_detail::void_caster *
[2] 0x004adb7c t const
boost::serialization::void_cast_detail::void_caster *
[3] 0x004adbb0 t const
boost::serialization::void_cast_detail::void_caster *
[4] 0x003981e0 {m_includes_virtual_base=true } const
boost::serialization::void_cast_detail::void_caster *
[5] 0x004adce0 t const
boost::serialization::void_cast_detail::void_caster *
[6] 0x004add14 t const
boost::serialization::void_cast_detail::void_caster *
[7] 0x00398298 {m_includes_virtual_base=true } const
boost::serialization::void_cast_detail::void_caster *
[8] 0x00397a18 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
[9] 0x003943c8 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
[10] 0x004adb48 t const
boost::serialization::void_cast_detail::void_caster *
[11] 0x00398350 {m_includes_virtual_base=true } const
boost::serialization::void_cast_detail::void_caster *
}}}
----
NG Case
||No||r-level||vb||Derived||Base||Action||!OverWrite||
||0||||false||Sub1||Mid1||-||||
||1||||false||Sub1||Mid2||-||||
||2||||false||Target||Sub2||-||||
||3||||true||Mid1||VBase||match A Mid1 No.0,add No.4||||
||4||1||true||Sub1||VBase||-||||
||5||||true||Mid2||VBase||match A Mid2 No.1,add No.6||||
||6||1||true||Sub1||VBase||-||No.4||
||7||||false||Sub2||Mid1||match B Mid1 No.3,add No.8||||
||||||||||||match A Sub2 No.2,add No.10||||
||8||1||false||Sub2||VBase||match A Sub2 No.2,add No.9||||
||9||2||false||Target||VBase||-||||
||10||1||false||Target||Mid1||match B Mid1 No.3,add No.11||||
||11||2||false||Target||VBase||-||No.9||
||12||||false||Sub2||Mid2||match B Mid2 No.5,add No.13||||
||||||||||||match A Sub2 No.2,add No.15||||
||13||1||false||Sub2||VBase||match A Sub2 No.2,add No.14||No.8||
||14||2||false||Target||VBase||-||No.9||
||15||1||false||Target||Mid2||match B Mid2 No.5,add No.16||||
||16||2||false||Target||VBase||-||No.9||
Result (focus on m_includes_virtual_base)
{{{
[0] 0x004adce0 t const
boost::serialization::void_cast_detail::void_caster *
[1] 0x004add14 t const
boost::serialization::void_cast_detail::void_caster *
[2] 0x004adb48 t const
boost::serialization::void_cast_detail::void_caster *
[3] 0x004adb7c t const
boost::serialization::void_cast_detail::void_caster *
[4] 0x00397a18 {m_includes_virtual_base=true } const
boost::serialization::void_cast_detail::void_caster *
[5] 0x004add48 t const
boost::serialization::void_cast_detail::void_caster *
[6] 0x004add7c t const
boost::serialization::void_cast_detail::void_caster *
[7] 0x00398190 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
[8] 0x00398300 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
[9] 0x00398540 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
[10] 0x004adbb0 t const
boost::serialization::void_cast_detail::void_caster *
[11] 0x00398248 {m_includes_virtual_base=false } const
boost::serialization::void_cast_detail::void_caster *
}}}
----
m_includes_virtual_base is different in OK case and NG case.
Probably it is the reason of access violation.
I think that there is a problem in void_caster::recursive_register
algorithm.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3604> 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:01 UTC