Boost C++ Libraries: Ticket #3014: Assertion on unregistering of extended_type_info https://svn.boost.org/trac10/ticket/3014 <p> /With boost version 1.39.0 I got the following behavior. On exit from the program an assertion assert(NULL != l) in extended_type_info.cpp:47 failed. After some debugging I have revealed that same instances of extended_type_info were registered by extended_type_info::key_register() several times (about 3-4 times each). I am not sure if it is normal. The program which I debugged, staticaly links a library, and this library includes same headers with serializable classes as the program. Anyway, the multimap returned by singleton&lt;detail::ktmap&gt;::get_mutable_instance() may contain extended_type_info instances with the same m_key. BUT in extended_type_info::key_register():103, after removal of type info from the multimap, the value of m_key is being NULLed (m_key = NULL). Therefore, if this instance of extended_type_info is contained in the multimap at least once, it will make the next call of lower_bound to fail, because it has NULL in its m_key. </p> <p> As a temporary fix I have commented out the the following strings <em>assert(start != end); and </em>m_key = NULL; I removed the assertion because now the check in extended_type_info destructor may not work and key_unregister() method may be called for an instance allready removed from the multiset. </p> <p> I suppose that multiple registration can be caused by anonymous namespace introduced in export.hpp file around guid_initializer, but I didn't make deep investigations. </p> <p> The initial issue was observed on Win-32 + mingw-gcc.4.3 </p> <blockquote> <p> and on </p> </blockquote> <p> Ubuntu-Linux-64 + gcc.4.3 </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3014 Trac 1.4.3 mazay0@… Sun, 10 May 2009 18:58:00 GMT attachment set https://svn.boost.org/trac10/ticket/3014 https://svn.boost.org/trac10/ticket/3014 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">extended_type_info.diff</span> </li> </ul> <blockquote> <p> fix for extended_type_info.cpp </p> </blockquote> Ticket Robert Ramey Mon, 11 May 2009 20:10:43 GMT status changed https://svn.boost.org/trac10/ticket/3014#comment:1 https://svn.boost.org/trac10/ticket/3014#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Robert Ramey Mon, 18 May 2009 16:08:53 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3014#comment:2 https://svn.boost.org/trac10/ticket/3014#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> I have made changes to extended_type_info.cpp and void_cast.cpp in the trunk. I can't really test these very well. I would appreciate it if you could rebuild the library with these latest files and try again. </p> <p> Robert Ramey </p> Ticket Mazay0@… Tue, 19 May 2009 05:12:17 GMT attachment set https://svn.boost.org/trac10/ticket/3014 https://svn.boost.org/trac10/ticket/3014 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">minimal_example_boost3014.zip</span> </li> </ul> <p> Minimal example to reproduce the issue </p> Ticket mazay0@… Tue, 19 May 2009 05:13:34 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/3014#comment:3 https://svn.boost.org/trac10/ticket/3014#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3014#comment:2" title="Comment 2">ramey</a>: </p> <blockquote class="citation"> <p> ... </p> </blockquote> <p> Unfortunately this fix doesn't help. I've managed to create a minimal example which repoduce the bug (see attach <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/3014/minimal_example_boost3014.zip"><span class="icon">​</span>https://svn.boost.org/trac/boost/attachment/ticket/3014/minimal_example_boost3014.zip</a>). Put breakpoints in key_register() and key_unregister() methods to meditate on the issue. As far as I understand the key_register() method is being invoked by guid_initializer from every translation unit which includes BOOST_CLASS_EXPORT_GUID macro. So two pointers to the same instance of extended_type_info appears in ktmap multiset. When key_unregister() is beig called first time everything works fine, but only one pointer is being erased from ktmap. The other one stays there and points to extended_type_info object with nulled m_key field. So, when key_unregister() is called at second time (no mater for which type), the lower_bound() call blows up on this mine. </p> Ticket Mazay0@… Tue, 19 May 2009 05:32:53 GMT <link>https://svn.boost.org/trac10/ticket/3014#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3014#comment:4</guid> <description> <p> At first sight there is three possible fixes: 1) Additional check in key_register() to avoid duplicates in ktmap (Also I don't understand why ktmap is a multiset in spite of a simple set). 2) Remove break; from key_unregister() and null m_key only after erasing of all occurences of this extended_type_info. 3) Split declaration and definition of guid_initializer. Make two macroses BOOST_CLASS_EXPORT_GUID_DECLARE and BOOST_CLASS_EXPORT_GUID_DEFINE. This whould allow user to explicitly specify translational unit in which an instance of guid_initializer should be created. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Tue, 19 May 2009 21:20:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3014#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3014#comment:5</guid> <description> <p> "(Also I don't understand why ktmap is a multiset in spite of a simple set)." </p> <p> THe problem can occur during the dynamic loading and unloading of DLLS where there the same code is instantiated in multiple modules. when a dll is unloaded, one has to take care that the correct registry entries are deleted so as not too leave any dangling pointers. </p> <p> I believe this problem will not occure if BOOST_CLASS_EXPORT is only included inside an implementation file rather than a header. </p> <p> I'm still looking at this. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Sat, 30 May 2009 22:27:24 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3014#comment:6 https://svn.boost.org/trac10/ticket/3014#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">worksforme</span> </li> </ul> <p> I've built and tested this minimal example on my VC 7.1 system and it compiles, links and runs without error. Our differing results might be due to one of the following: </p> <p> a) different development system b) I made a change sometime ago to address this. I think my local copy of extended type info is in sync with the trunk. Maybe we're out of sync with this. </p> <p> Robert Ramey </p> Ticket Mazay0@… Sun, 31 May 2009 14:33:41 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/3014#comment:7 https://svn.boost.org/trac10/ticket/3014#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">worksforme</span> </li> </ul> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3014#comment:6" title="Comment 6">ramey</a>: </p> <blockquote class="citation"> <p> I've built and tested this minimal example on my VC 7.1 system and it compiles, links and runs without error. </p> </blockquote> <p> I have traced the exmaple on VC 7.1. It runs without errors because singleton&lt;detail::ktmap&gt; dies between destructions of extented_type_info instances for Foo and Bar classes (after Bar, before Foo). Therefore, the check if(! singleton&lt;detail::ktmap&gt;::is_destroyed()) in extended_type_info::key_unregister() saves the program from attempt to do something with ktmap, which contains "invalid" extented_type_info instance. AFAIU in this case destruction order is undefined. Hence I suppose that this is UB. </p> <p> Is it safe to try to avoid multiple insertion of the same extended_type_info instances in ktmap? It seems that m_key value can be used as an indicator if this extended_type_info is registered in ktmap. It is used in this manner in ~extended_type_info(). May be we can do the similar check in key_register()? </p> <pre class="wiki">BOOST_SERIALIZATION_DECL(void) extended_type_info::key_register(const char *key) { assert(NULL != key); if (m_key == NULL) { m_key = key; singleton&lt;detail::ktmap&gt;::get_mutable_instance().insert(this); } } </pre> Ticket eric.woodruff@… Wed, 03 Jun 2009 16:45:31 GMT <link>https://svn.boost.org/trac10/ticket/3014#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3014#comment:8</guid> <description> <p> Mazay0, I've hit this same issue after updating to 1.39 and your suggestion of avoiding inserting multiple instances in ktmap in key_register fixes my issue. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Thu, 09 Jul 2009 14:57:07 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3014#comment:9 https://svn.boost.org/trac10/ticket/3014#comment:9 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> I believe that I've checked into the trunk changes which resolve this issue. </p> Ticket eric.woodruff@… Wed, 09 Sep 2009 04:21:36 GMT <link>https://svn.boost.org/trac10/ticket/3014#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3014#comment:10</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3014#comment:9" title="Comment 9">ramey</a>: </p> <blockquote class="citation"> <p> I believe that I've checked into the trunk changes which resolve this issue. </p> </blockquote> <p> FYI - I hit this again on 1.40. I still need to apply the suggested patch by Mazzy0 to get a successful unit test run. I tried to find the changes on the trunk that fixed this issue, but couldn't. ramey, could you attach the patch to this bug? </p> </description> <category>Ticket</category> </item> <item> <author>mazay0@…</author> <pubDate>Fri, 23 Aug 2013 05:23:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3014#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3014#comment:11</guid> <description> <p> Just in case: The problem is fixed since 1.41.0: <a href="http://www.boost.org/doc/libs/1_41_0/libs/serialization/doc/traits.html#export">http://www.boost.org/doc/libs/1_41_0/libs/serialization/doc/traits.html#export</a> </p> <hr /> <p> This is addressed by invoking <em> <strong>BOOST_CLASS_EXPORT_IMPLEMENT</strong>(T) in the file which defines (implements) the class T</em>. This ensures that code for the derived class T will be explicity instantiated. </p> <p> ... </p> <p> So in the serialization library, this is addressed by invoking <em> <strong>BOOST_CLASS_EXPORT_KEY2(my_class, "my_class_external_identifier")</strong> in the header file which declares he class</em>. </p> <p> ... </p> <p> For programs which consist of only one module - that is programs which do not use DLLS, one can specify BOOST_CLASS_EXPORT(my_class) or BOOST_CLASS_EXPORT_GUID(my_class, "my_class_external_identifier") in either he declaration header or definition. </p> </description> <category>Ticket</category> </item> </channel> </rss>