|
Boost Users : |
From: Sergey Skorniakov (s.skorniakov_at_[hidden])
Date: 2007-08-16 03:31:47
I had looked into code and found that tracking and version information loaded from archive only if basic_iserializer::class_info returns true:
void
basic_iarchive_impl::load_preamble(
basic_iarchive & ar,
cobject_id & co
){
if(! co.initialized){
if(co.bis_ptr->class_info()){
class_id_optional_type cid;
load(ar, cid); // to be thrown away
load(ar, co.tracking_level);
load(ar, co.file_version);
}
else{
// override tracking with indicator from class information
co.tracking_level = co.bis_ptr->tracking(m_flags);
co.file_version = version_type(
co.bis_ptr->version()
);
}
co.initialized = true;
}
}
So, for all types that has implementation_level less than object_class_info (standard library collections of primitive types has object_serializable implementation_level) information about tracking (and version) are generated in-place depending of presence appropriate instance of pointer_iserializer<Archive, T> in code. I think, it is very dangerous solution. May be, it's better to consider track_selectivly as track_always in such a situation.
The different behavior of xml archives explained by diferent implementation of loading object_id - xml archive just returns already parsed attribute (it gives object_id of last loaded object with object_id or uninitialized value), but other archives performs actual reading that leads into various troubles, depending of archive content.
"Robert Ramey" <ramey_at_[hidden]> wrote in message news:f9v7mj$q98$1_at_sea.gmane.org...
> Robert Ramey wrote:
>> OK - I see the problem - good example. I don't see an obvious or
>> easy fix. I'll look into it.
>>
> Thinking about this some more.
>
>> Sergey Skorniakov wrote:
>>> Unfortunately, current tracking implementation can also leads to
>>> weird version incompatibility. The unlucky combination is
>>> object_serializable + track_selectivly. Suppose, someone have code
>>> that serizalizes vector<int> to file (by value). After some time,
>>> some code that serializes vector<int> as pointer is added to program.
>>> Its enough to make old files unreadable (or readable with errors).
>
> This issue was considered in the implemenation. The fact that at type
> is tracked/untracked is written to the archive when the data is saved.
> Tracking at load time is determined by the corresponding flag in the
> archive and NOT the current attribute.
>
> Soooo this will have to be looked into. standard library collections
> are a little different in that they are unversioned. I don't know if that
> makes a difference, but we'll look into it. Its also very odd the
> behavior is different depending upon the type of archive.
>
> Robert Ramey
>
>>> Sample code:
>>>
>>> void TestTrack2Err(boost::archive::polymorphic_xml_iarchive &ar)
>>> {
>>> std::vector<int> *p;
>>> ar & BOOST_SERIALIZATION_NVP(p);
>>> // saving of vector<int>* is absent intentionaly to simulate
>>> different versions of saving and loading code }
>>> void TestTrack2()
>>> {
>>> std::stringstream s;
>>> std::vector<int> x;
>>> x.push_back(4);
>>> {
>>> boost::archive::polymorphic_text_oarchive ar(s);
>>> ar & BOOST_SERIALIZATION_NVP(x);
>>> }
>>> x.clear();
>>> {
>>> boost::archive::polymorphic_text_iarchive ar(s);
>>> ar & BOOST_SERIALIZATION_NVP(x);
>>> assert(x.size() == 1); // The vector is empty at this point -
>>> unless loading of vector<int>* is commented out }
>>> }
>>>
>>> The consequences of error can vary from noting (especially with xml
>>> archives) to program crashes in some more difficult cases. I have
>>> recently encountered this error when dealing with a big project (more
>>> than 500 serialized types) and have no idea how I can get out of a
>>> difficulty.
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