
Hi, I've had another crash related to basic_iarchive, bpis_ptr being NULL, when using serialization in DLLs. I found two occurences of this bug. The basic reason is the same, singletons are created in each DLL that serializes the type, but the occurence happens at different places in the basic_iarchive code. Case 1: DLL_1 has serialization code for VxVector3 (amongst other classes). DLL_1 creates singletons iserializer<Archive, VxVector3> and pointer_iserializer<Archive, VxVector3> DLL_2 does NOT have serialization code for VxVector3 DLL_2 creates a singleton iserializer<Archive, VxVector3> only VxVector3 is never serialized as a pointer in DLL_2. When loading, basic_iarchive::cobject_id_vector is built as the objects are read. Every time a an object (not a pointer) is read, it goes through basic_iarchive_impl::register_type wich will look in cobject_id_vector to register the type if needed. In the sequence of operation, it happpened that the first time a VxVector object is read is triggered by DLL_1. cobject_id_vector is initialised with the two serializer for that type. Good. However, later in the file, another VxVector3 is read, but this time it is triggered by DLL_2. Which loooks through the cobject_id_vector, find that the type is already registered, but then overwrite the bpis_ptr with NULL in the entry for VxVector3. Later in the file, we want to load a VxVector3* (triggered from DLL_1), but the bpis_ptr has been removed: boom! Case 2: using the same serialization DLLs DLL_1 has serialization code for VxOutput DLL_1 creates singletons iserializer<Archive, VxOutput> and pointer_iserializer<Archive, VxOutput> DLL_2 does NOT have serialization code for VxOutput DLL_2 creates a singleton iserializer<Archive, VxOutput> only VxOutput is never serialized as a pointer in DLL_2. Here, a different file is being deserialized. The first time that VxOutput is read, as an object, it is triggered from DLL_2. This registers VxOutput to cobject_id_vector but with only iserializer since iserializer created in DLL_2 does not know of any pointer_iserializer for VxOutput. Later, a VxOutput* is read, triggered by DLL_1. This goes to basic_iarchive_impl::load_pointer, the class id is already registered, all looks good BUT in cobject_id_vector for VxOutput, bpis_ptr is NULL: boom! Locally, I've done fixes that will take care of those two cases and load them correctly, but they are hacks and they do not fix the real problem. In addition, that problem depends on the order of operations, I cannot be certain that all cases were found. I'm beginning to think that the real problem is not the duplicatio of singletons in different DLLs for the same class. The iserializer and pointer_iserializer that come from different DLLs are different object but they are equally valid. I tend to see the duplication as a side effect of using DLLs in the first place. The archive_serializer_map<Archive> contains all the pointer_serializer for a specific archive type, it is global, unique, and could be used consistently to get the pointer_iserializer, instead of relying on the pointer_iserializer known (or not) by the iserializer. There seem to be fewer issues with oserializer and pointer_oserializer. I haven't looked at it in detail, but the only problem I had was with the track_selectively. With DLL_1 and DLL_2, tracking would be different whether saving is triggered the first time from DLL_1 or DLL_2, since it looks for the presence of an pointer_oserializer associated with the oserializer in basic_oarchive_impl::cobject_info_set. Again, using archive_serializer_map<Archive> might just do the trick. That issue is clearer to me now, however it is still not clear how to fix it. Guy Prémont -- Guy Prémont, D.Sc. Architecte logiciel senior / Senior software architect CM Labs Simulations Inc. http://www.cm-labs.com/ Tel. 514-287-1166 ext. 237