serialization 1.36.0 extended_type_info exit issue(s)

Folks, I'm running some serialization unit-tests which pass with flying colors under 1.35.0 and earlier, however they seg-fault on exit when run through 1.36.0. The error appears to deal with destruction of extended_type_info_typeid objects, and *only* manifests itself when I load an archive through a shared_ptr<T>. The load will appear to function properly, then on exit of the application, <<Death>>. This occurs even if I remove BOOST_CLASS_EXPORT && BOOST_CLASS_TYPE_INFO as the shared_ptr is to the derived element, and I'm not testing through a base. My lastest guess is that I may be missing some #define BOOST_SOME_MAGIC_NEW_OPTION //////////////////////////// pseduo code: //////////////////////////// BOOST_AUTO_TEST_CASE( MyTestClass_Serialization ) { boost::shared_ptr<MyTestClass> outtie ( new MyTestClass() ); boost::shared_ptr<MyTestClass> innie; std::ofstream os( "MyTestClass_Serialization.xml", std::ios_base::out ); my_pack< MyTestClass >( os, outtie ); os.close(); std::ifstream is( "MyTestClass_Serialization.xml", std::ios_base::in ); my_unpack< MyTestClass >( is, innie ); is.close(); BOOST_CHECK_NO_THROW(); } //////////////////////////// ddd output: //////////////////////////// *** No errors detected [New Thread 0xb73e26c0 (LWP 4715)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb73e26c0 (LWP 4715)] 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 (gdb) bt #0 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 #1 0xb7a38221 in std::_Rb_tree<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::extended_type_info_typeid_0 const*, std::_Identity<boost::serialization::detail::extended_type_info_typeid_0 const*>, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_tree.h:1261 #2 0xb7a38270 in std::multiset<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_multiset.h:346 #3 0xb7a37482 in boost::serialization::detail::extended_type_info_typeid_0::type_unregister (this=0x810749c) at /opt/tomodev/env/boost/libs/serialization/src/extended_type_info_typeid.cpp:93 #4 0x080b001a in ~extended_type_info_typeid (this=0x810749c) at /opt/tomodev/env/boost/boost/serialization/extended_type_info_typeid.hpp:80 #5 0x0809ebe2 in __tcf_49 () at /opt/tomodev/env/boost/boost/serialization/singleton.hpp:104 #6 0xb74f7084 in exit () from /lib/tls/i686/cmov/libc.so.6 #7 0xb74df458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #8 0x0809e691 in _start () Cheers, Timothy St. Clair [timothysc@gmail.com]

More likely a bug introduced by recent improvements in handling automatic registering/deregistering. Please make a small test case (below isn't complete) along with information about compiler, os, etc and open up a TRAK item. Robert Ramey "Tim St. Clair" <timothysc@gmail.com> wrote in message news:ef85fd8f0808181251s3356849fl9288d1a9c9c0486b@mail.gmail.com... Folks, I'm running some serialization unit-tests which pass with flying colors under 1.35.0 and earlier, however they seg-fault on exit when run through 1.36.0. The error appears to deal with destruction of extended_type_info_typeid objects, and *only* manifests itself when I load an archive through a shared_ptr<T>. The load will appear to function properly, then on exit of the application, <<Death>>. This occurs even if I remove BOOST_CLASS_EXPORT && BOOST_CLASS_TYPE_INFO as the shared_ptr is to the derived element, and I'm not testing through a base. My lastest guess is that I may be missing some #define BOOST_SOME_MAGIC_NEW_OPTION //////////////////////////// pseduo code: //////////////////////////// BOOST_AUTO_TEST_CASE( MyTestClass_Serialization ) { boost::shared_ptr<MyTestClass> outtie ( new MyTestClass() ); boost::shared_ptr<MyTestClass> innie; std::ofstream os( "MyTestClass_Serialization.xml", std::ios_base::out ); my_pack< MyTestClass >( os, outtie ); os.close(); std::ifstream is( "MyTestClass_Serialization.xml", std::ios_base::in ); my_unpack< MyTestClass >( is, innie ); is.close(); BOOST_CHECK_NO_THROW(); } //////////////////////////// ddd output: //////////////////////////// *** No errors detected [New Thread 0xb73e26c0 (LWP 4715)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb73e26c0 (LWP 4715)] 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 (gdb) bt #0 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 #1 0xb7a38221 in std::_Rb_tree<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::extended_type_info_typeid_0 const*, std::_Identity<boost::serialization::detail::extended_type_info_typeid_0 const*>, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_tree.h:1261 #2 0xb7a38270 in std::multiset<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_multiset.h:346 #3 0xb7a37482 in boost::serialization::detail::extended_type_info_typeid_0::type_unregister (this=0x810749c) at /opt/tomodev/env/boost/libs/serialization/src/extended_type_info_typeid.cpp:93 #4 0x080b001a in ~extended_type_info_typeid (this=0x810749c) at /opt/tomodev/env/boost/boost/serialization/extended_type_info_typeid.hpp:80 #5 0x0809ebe2 in __tcf_49 () at /opt/tomodev/env/boost/boost/serialization/singleton.hpp:104 #6 0xb74f7084 in exit () from /lib/tls/i686/cmov/libc.so.6 #7 0xb74df458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #8 0x0809e691 in _start () Cheers, Timothy St. Clair [timothysc@gmail.com] ------------------------------------------------------------------------------ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

I submitted a bug, let me know if you require more info, I believe it's pretty complete. Cheers, Tim On Mon, Aug 18, 2008 at 4:31 PM, Robert Ramey <ramey@rrsd.com> wrote:
More likely a bug introduced by recent improvements in handling automatic registering/deregistering.
Please make a small test case (below isn't complete) along with information about compiler, os, etc and open up a TRAK item.
Robert Ramey
"Tim St. Clair" <timothysc@gmail.com> wrote in message news:ef85fd8f0808181251s3356849fl9288d1a9c9c0486b@mail.gmail.com... Folks,
I'm running some serialization unit-tests which pass with flying colors under 1.35.0 and earlier, however they seg-fault on exit when run through 1.36.0.
The error appears to deal with destruction of extended_type_info_typeid objects, and *only* manifests itself when I load an archive through a shared_ptr<T>. The load will appear to function properly, then on exit of the application, <<Death>>. This occurs even if I remove BOOST_CLASS_EXPORT && BOOST_CLASS_TYPE_INFO as the shared_ptr is to the derived element, and I'm not testing through a base.
My lastest guess is that I may be missing some #define BOOST_SOME_MAGIC_NEW_OPTION
//////////////////////////// pseduo code: //////////////////////////// BOOST_AUTO_TEST_CASE( MyTestClass_Serialization ) { boost::shared_ptr<MyTestClass> outtie ( new MyTestClass() ); boost::shared_ptr<MyTestClass> innie;
std::ofstream os( "MyTestClass_Serialization.xml", std::ios_base::out ); my_pack< MyTestClass >( os, outtie ); os.close();
std::ifstream is( "MyTestClass_Serialization.xml", std::ios_base::in ); my_unpack< MyTestClass >( is, innie ); is.close();
BOOST_CHECK_NO_THROW(); }
//////////////////////////// ddd output: //////////////////////////// *** No errors detected [New Thread 0xb73e26c0 (LWP 4715)]
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb73e26c0 (LWP 4715)] 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 (gdb) bt #0 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 #1 0xb7a38221 in std::_Rb_tree<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::extended_type_info_typeid_0 const*, std::_Identity<boost::serialization::detail::extended_type_info_typeid_0 const*>, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_tree.h:1261 #2 0xb7a38270 in std::multiset<boost::serialization::detail::extended_type_info_typeid_0 const*, boost::serialization::detail::type_compare, std::allocator<boost::serialization::detail::extended_type_info_typeid_0 const*> >::erase (this=0xb7a93c94, __position={_M_node = 0x810a3f8}) at /usr/include/c++/4.2/bits/stl_multiset.h:346 #3 0xb7a37482 in boost::serialization::detail::extended_type_info_typeid_0::type_unregister (this=0x810749c) at /opt/tomodev/env/boost/libs/serialization/src/extended_type_info_typeid.cpp:93 #4 0x080b001a in ~extended_type_info_typeid (this=0x810749c) at /opt/tomodev/env/boost/boost/serialization/extended_type_info_typeid.hpp:80 #5 0x0809ebe2 in __tcf_49 () at /opt/tomodev/env/boost/boost/serialization/singleton.hpp:104 #6 0xb74f7084 in exit () from /lib/tls/i686/cmov/libc.so.6 #7 0xb74df458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #8 0x0809e691 in _start ()
Cheers, Timothy St. Clair [timothysc@gmail.com]
------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Regards, Timothy St. Clair [timothysc@gmail.com]

Tim St. Clair writes:
I'm running some serialization unit-tests which pass with flying colors under 1.35.0 and earlier, however they seg-fault on exit when run through 1.36.0. ... Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb73e26c0 (LWP 4715)] 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6
I am having similar problems, only there are no shared pointers involved. I was getting this segv also, but as I pared the example down and it mutated into a memory corruption problem: *** glibc detected *** ./serio: double free or corruption (fasttop): 0x0805c5c8 *** ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6[0xb7cd5a85] /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7cd94f0] /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7ea1b11] /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_36.so.1.36.0(_ZN5boost13serialization6detail27extended_type_info_typeid_015type_unregisterEv+0xf6)[0xb7f3c8d6] ./serio(_ZN5boost13serialization25extended_type_info_typeidI4DataED1Ev+0x1c)[0x805576a] ./serio(__gxx_personality_v0+0x35e)[0x8053f36] /lib/tls/i686/cmov/libc.so.6(exit+0xd4)[0xb7c98084] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe8)[0xb7c80458] ./serio(__gxx_personality_v0+0x69)[0x8053c41] The problem I'm experiencing only seems to occur when the class implementation is in a shared library. I have attached a simple example that reproduces the bug. My system details are: Intel i686 cpu Ubuntu Hardy Heron g++ (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7) libstdc++6-4.2-dev 4.2.3-2ubuntu7 Boost 1.36.0 ./configure --prefix=/home/mecklen/work/boost-install \ --without-libraries=python \ --without-icu --without-mpi This is a real show-stopper for us. Any help would be greatly appreciated. Thanks, -- Robert // g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serio.cpp -o serio -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -lboost_unit_test_framework-gcc42-mt #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #include <boost/test/auto_unit_test.hpp> #include <boost/archive/text_oarchive.hpp> #include <sstream> struct Data { Data() : n_(10) {} template <class Archive> void serialize(Archive & ar, const unsigned version); int n_; }; BOOST_AUTO_TEST_CASE(serioTest) { Data d; std::ostringstream os; boost::archive::text_oarchive oa(os); oa & d; // <<<<< Remove this and no crash. } #include <boost/archive/text_oarchive.hpp> // serialization::text_oarchive #include <boost/serialization/export.hpp> struct Data { Data() : n_(10) {} template <class Archive> void serialize(Archive & ar, const unsigned version); int n_; }; BOOST_CLASS_EXPORT(Data); template <class Archive> void Data::serialize(Archive & ar, const unsigned /* version */) { ar & n_; } #! /bin/bash -x rm -f serioblob.o libserioblob.so serio.o serio g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serioblob.cpp -c -o serioblob.o g++ -g -ftrapv -DBOOST_1_36_0 -I/home/mecklen/work/boost-install/include/boost-1_36 -DUSE_TRAPV -rdynamic -shared serioblob.o -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -o libserioblob.so g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serio.cpp -c -o serio.o g++ -g -ftrapv -DBOOST_1_36_0 -I/home/mecklen/work/boost-install/include/boost-1_36 -DUSE_TRAPV -rdynamic serio.o libserioblob.so /home/mecklen/work/boost-install/lib/libboost_unit_test_framework-gcc42-mt.so -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -o serio export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mecklen/work/boost-install/lib:. ./serio --catch_system_errors=no

This has been reported in two trak items. I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet. Robert. Robert Mecklenburg wrote:
Tim St. Clair writes:
I'm running some serialization unit-tests which pass with flying colors under 1.35.0 and earlier, however they seg-fault on exit when run through 1.36.0. ... Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb73e26c0 (LWP 4715)] 0xb76bb56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6
I am having similar problems, only there are no shared pointers involved. I was getting this segv also, but as I pared the example down and it mutated into a memory corruption problem:
*** glibc detected *** ./serio: double free or corruption (fasttop): 0x0805c5c8 *** ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6[0xb7cd5a85] /lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7cd94f0] /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7ea1b11]
/home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_36.so.1.36.0(_ZN5boost13serialization6detail27extended_type_info_typeid_015type_unregisterEv+0xf6)[0xb7f3c8d6] ./serio(_ZN5boost13serialization25extended_type_info_typeidI4DataED1Ev+0x1c)[0x805576a] ./serio(__gxx_personality_v0+0x35e)[0x8053f36] /lib/tls/i686/cmov/libc.so.6(exit+0xd4)[0xb7c98084] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe8)[0xb7c80458] ./serio(__gxx_personality_v0+0x69)[0x8053c41]
The problem I'm experiencing only seems to occur when the class implementation is in a shared library. I have attached a simple example that reproduces the bug.
My system details are:
Intel i686 cpu Ubuntu Hardy Heron g++ (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7) libstdc++6-4.2-dev 4.2.3-2ubuntu7 Boost 1.36.0 ./configure --prefix=/home/mecklen/work/boost-install \ --without-libraries=python \ --without-icu --without-mpi
This is a real show-stopper for us. Any help would be greatly appreciated.
Thanks, -- Robert
// g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serio.cpp -o serio -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -lboost_unit_test_framework-gcc42-mt
#define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN
#include <boost/test/auto_unit_test.hpp> #include <boost/archive/text_oarchive.hpp> #include <sstream>
struct Data { Data() : n_(10) {} template <class Archive> void serialize(Archive & ar, const unsigned version); int n_; };
BOOST_AUTO_TEST_CASE(serioTest) { Data d; std::ostringstream os; boost::archive::text_oarchive oa(os);
oa & d; // <<<<< Remove this and no crash. }
#include <boost/archive/text_oarchive.hpp> // serialization::text_oarchive #include <boost/serialization/export.hpp>
struct Data { Data() : n_(10) {} template <class Archive> void serialize(Archive & ar, const unsigned version); int n_; };
BOOST_CLASS_EXPORT(Data);
template <class Archive> void Data::serialize(Archive & ar, const unsigned /* version */) { ar & n_; }
#! /bin/bash -x rm -f serioblob.o libserioblob.so serio.o serio
g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serioblob.cpp -c -o serioblob.o
g++ -g -ftrapv -DBOOST_1_36_0 -I/home/mecklen/work/boost-install/include/boost-1_36 -DUSE_TRAPV -rdynamic -shared serioblob.o -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -o libserioblob.so
g++ -I/home/mecklen/work/boost-install/include/boost-1_36 serio.cpp -c -o serio.o
g++ -g -ftrapv -DBOOST_1_36_0 -I/home/mecklen/work/boost-install/include/boost-1_36 -DUSE_TRAPV -rdynamic serio.o libserioblob.so /home/mecklen/work/boost-install/lib/libboost_unit_test_framework-gcc42-mt.so -L/home/mecklen/work/boost-install/lib/ -lboost_serialization-gcc42-mt -o serio
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/mecklen/work/boost-install/lib:. ./serio --catch_system_errors=no
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Robert Ramey writes:
This has been reported in two trak items.
Sorry to waste bandwidth.
I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet.
Is there any way I can help test your patch? Thanks, -- Robert

Robert Ramey wrote:
This has been reported in two trak items.
I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet.
Robert.
Hey Robert, Got any hints on what is going on here? svn revision# of the relevant changes? We've hit this one as well, looking for a workaround, not making much progress. -t

I've addressed it on my personal copy. Just now passed tests on my local machine. I will be uploading to the trunk soon. Unfortunately I can't be sure my changes fix the problem as it doesn't manifest itself on my machine. Robert Ramey troy d. straszheim wrote:
Robert Ramey wrote:
This has been reported in two trak items.
I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet.
Robert.
Hey Robert,
Got any hints on what is going on here? svn revision# of the relevant changes? We've hit this one as well, looking for a workaround, not making much progress.
-t

Robert Ramey wrote:
I've addressed it on my personal copy. Just now passed tests on my local machine. I will be uploading to the trunk soon. Unfortunately I can't be sure my changes fix the problem as it doesn't manifest itself on my machine.
OK, just ping this thread, I'll give it some exercise. Thanks, -t

Will this fix show up in a 1.36.1 release or not until 1.37.0. Can you provide me the svn version number that has the fix? Robert Ramey wrote:
I've addressed it on my personal copy. Just now passed tests on my local machine. I will be uploading to the trunk soon. Unfortunately I can't be sure my changes fix the problem as it doesn't manifest itself on my machine.
Robert Ramey
troy d. straszheim wrote:
Robert Ramey wrote:
This has been reported in two trak items.
I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet.
Robert.
Hey Robert,
Got any hints on what is going on here? svn revision# of the relevant changes? We've hit this one as well, looking for a workaround, not making much progress.
-t
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Its currently in the trunk - head version. I can't test it and it doesn't fail on any test platforms, so its up to you guys to test it. Robert Ramey Ken Roser wrote:
Will this fix show up in a 1.36.1 release or not until 1.37.0.
Can you provide me the svn version number that has the fix?
Robert Ramey wrote:
I've addressed it on my personal copy. Just now passed tests on my local machine. I will be uploading to the trunk soon. Unfortunately I can't be sure my changes fix the problem as it doesn't manifest itself on my machine.
Robert Ramey
troy d. straszheim wrote:
Robert Ramey wrote:
This has been reported in two trak items.
I've looked at it and made changes which I believe will address the problem. But I haven't been able to test it yet.
Robert.
Hey Robert,
Got any hints on what is going on here? svn revision# of the relevant changes? We've hit this one as well, looking for a workaround, not making much progress.
-t
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Robert Ramey writes:
Its currently in the trunk - head version. I can't test it and it doesn't fail on any test platforms, so its up to you guys to test it.
I checked out the trunk and tested some of my code. Of the five classes I tested, four unit tests now pass cleanly. One of them still seg faults with the same stack trace as before. (gdb) where #0 std::_Rb_tree_rebalance_for_erase (__z=0x8072fb8, __header=@0xb7bfbde0) at ../../../../src/libstdc++-v3/src/tree.cc:337 #1 0xb7bc9f93 in boost::serialization::extended_type_info::key_unregister () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #2 0xb7bca0ef in boost::serialization::extended_type_info::~extended_type_info () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #3 0xb7bcaa28 in boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0 () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #4 0xb7690084 in exit () from /lib/tls/i686/cmov/libc.so.6 #5 0xb7678458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #6 0x0805c0c1 in _start () I don't really see any difference between the classes that work versus the one that fails, except that the failure has more nested classes, but it isn't particularly more complex. Let me know if you want more info on the failing class. BTW, Intel(R) Core(TM)2 CPU Ubuntu Hardy Heron g++ 4.2.3 Thanks for all your effort, -- Robert

I'm doubting that its the complexity of the class. More likely that its the "last" class. Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this. You should also run the test with break points set on ~singleton(){ m_is_destroyed = true; // <<< break here } To verify that this isn't getting called at an unexpected time. Robert Ramey Robert Mecklenburg wrote:
Robert Ramey writes:
Its currently in the trunk - head version. I can't test it and it doesn't fail on any test platforms, so its up to you guys to test it.
I checked out the trunk and tested some of my code. Of the five classes I tested, four unit tests now pass cleanly. One of them still seg faults with the same stack trace as before.
(gdb) where #0 std::_Rb_tree_rebalance_for_erase (__z=0x8072fb8, __header=@0xb7bfbde0) at ../../../../src/libstdc++-v3/src/tree.cc:337 #1 0xb7bc9f93 in boost::serialization::extended_type_info::key_unregister () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #2 0xb7bca0ef in boost::serialization::extended_type_info::~extended_type_info () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #3 0xb7bcaa28 in boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0 () from /home/mecklen/work/boost-install/lib/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #4 0xb7690084 in exit () from /lib/tls/i686/cmov/libc.so.6 #5 0xb7678458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #6 0x0805c0c1 in _start ()
I don't really see any difference between the classes that work versus the one that fails, except that the failure has more nested classes, but it isn't particularly more complex.
Let me know if you want more info on the failing class.
BTW,
Intel(R) Core(TM)2 CPU Ubuntu Hardy Heron g++ 4.2.3
Thanks for all your effort,

Robert Ramey writes:
I'm doubting that its the complexity of the class.
Sure, I agree. I was just trying to provide more info.
More likely that its the "last" class.
In the tests I am rrunning, each boost unit test is linked with its own main, so no two serialization tests run together. One of those tests fails.
Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this.
All of the individual tests are single threaded (although for build reasons they are linked with the mt libraries). That is, no test creates any additional threads.
You should also run the test with break points set on
~singleton(){ m_is_destroyed = true; // <<< break here }
To verify that this isn't getting called at an unexpected time.
I've done this and the destructor is called 15 times. It isn't obvious to me if this is unexpected (since this could be the base class of a hierarchy of singletons). Each time it is invoked on a different instance of this. Breakpoints and stack traces are at the end of this message. In the final call to ~singleton the object address is identical to the address of the ~extended_type_info object in the seg fault stack trace. Note that only the primary thread is ever created. Also, this unit test contains only a single top-level call to the serialization code. Of course, there are nested objects being serialized. Hope this helps. Let me know if there are more tests I can run. Thanks, -- Robert (gdb) list singleton.hpp:120 115 return get_instance(); 116 } 117 BOOST_DLLEXPORT static const T & get_const_instance(){ 118 return get_instance(); 119 } 120 BOOST_DLLEXPORT static bool is_destroyed(){ 121 return m_is_destroyed; 122 } 123 ~singleton(){ 124 m_is_destroyed = true; (gdb) b 124 Breakpoint 1 at 0x807ba0e: file /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp, line 124. (18 locations) (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/mecklen/s5w/trunk/core/common/src/test/SampleBinTest --catch_system_errors=no [Thread debugging using libthread_db enabled] Running 5 test cases... [New Thread 0xb73e16c0 (LWP 861)] *** No errors detected [Switching to Thread 0xb73e16c0 (LWP 861)] Breakpoint 1, ~singleton (this=0xb7f12294) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12294) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7dc4c65 in ~extended_type_info_typeid (this=0xb7f12294) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7dc42c4 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f126cc) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f126cc) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7dd7a5b in ~extended_type_info_typeid (this=0xb7f126cc) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7dd64d8 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f15384) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f15384) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e4c67b in ~extended_type_info_typeid (this=0xb7f15384) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e4a3f0 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f15544) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f15544) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e546cd in ~extended_type_info_typeid (this=0xb7f15544) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e50986 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f12db0) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12db0) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e26d55 in ~extended_type_info_typeid (this=0xb7f12db0) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e239e2 in __tcf_19 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f1245c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f1245c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7dc86d9 in ~extended_type_info_typeid (this=0xb7f1245c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7dc4fec in __tcf_14 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f123c4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f123c4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7dc85ad in ~extended_type_info_typeid (this=0xb7f123c4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7dc4fd8 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f1257c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f1257c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7dd3611 in ~extended_type_info_typeid (this=0xb7f1257c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7dd265c in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f12844) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12844) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7de138d in ~extended_type_info_typeid (this=0xb7f12844) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7ddffde in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f12cec) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12cec) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e26afd in ~extended_type_info_typeid (this=0xb7f12cec) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e239ba in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f157a4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f157a4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e6daaf in ~extended_type_info_typeid (this=0xb7f157a4) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e6c142 in __tcf_0 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f1541c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f1541c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e4c7a7 in ~extended_type_info_typeid (this=0xb7f1541c) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e4a404 in __tcf_14 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f12e54) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12e54) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e26e81 in ~extended_type_info_typeid (this=0xb7f12e54) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e239f6 in __tcf_24 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0xb7f12d84) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0xb7f12d84) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0xb7e26c29 in ~extended_type_info_typeid (this=0xb7f12d84) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0xb7e239ce in __tcf_18 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb75933b1 in __cxa_finalize () from /lib/tls/i686/cmov/libc.so.6 #4 0xb7dc4023 in __do_global_dtors_aux () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #5 0xb7e93a4c in _fini () from /home/mecklen/s5w/trunk/core/common/src/libcommon.so #6 0xb7f7afcf in _dl_fini () from /lib/ld-linux.so.2 #7 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #8 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #9 0x08077ce1 in _start () (gdb) cont Continuing. Breakpoint 1, ~singleton (this=0x8097d90) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 124 m_is_destroyed = true; (gdb) where #0 ~singleton (this=0x8097d90) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:124 #1 0x0807fe2d in ~extended_type_info_typeid (this=0x8097d90) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #2 0x08077f02 in __tcf_7 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #3 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #4 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #5 0x08077ce1 in _start () (gdb) cont Continuing. Program received signal SIGSEGV, Segmentation fault. std::_Rb_tree_rebalance_for_erase (__z=0x8098fb8, __header=@0xb7afede0) at ../../../../src/libstdc++-v3/src/tree.cc:337 337 ../../../../src/libstdc++-v3/src/tree.cc: No such file or directory. in ../../../../src/libstdc++-v3/src/tree.cc (gdb) where #0 std::_Rb_tree_rebalance_for_erase (__z=0x8098fb8, __header=@0xb7afede0) at ../../../../src/libstdc++-v3/src/tree.cc:337 #1 0xb7accf93 in boost::serialization::extended_type_info::key_unregister () from /home/mecklen/work/boost-install/lib/boost-1_37/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #2 0xb7acd0ef in boost::serialization::extended_type_info::~extended_type_info () from /home/mecklen/work/boost-install/lib/boost-1_37/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #3 0xb7acda28 in boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0 () from /home/mecklen/work/boost-install/lib/boost-1_37/libboost_serialization-gcc42-mt-1_37.so.1.37.0 #4 0x0807fe3e in ~extended_type_info_typeid (this=0x8097d90) at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/extended_type_info_typeid.hpp:80 #5 0x08077f02 in __tcf_7 () at /home/mecklen/work/boost-install/include/boost-1_37/boost/serialization/singleton.hpp:105 #6 0xb7593084 in exit () from /lib/tls/i686/cmov/libc.so.6 #7 0xb757b458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #8 0x08077ce1 in _start () (gdb)

Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this: valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test Specifically - what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above? I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this: 85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 90 detail::ktmap::iterator start = x.lower_bound(this); 91 detail::ktmap::iterator end = x.upper_bound(this); 92 assert(start != end); 93 94 // remove entry in map which corresponds to this type 95 do{ 96 if(this == *start) 97 x.erase(start++); 98 else 99 ++start; 100 }while(start != end); 101 } 102 m_key = NULL; 103 } instead of, say, 85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 97 x.erase(this); 101 } 102 m_key = NULL; 103 } Thanks in advance, -t Robert Mecklenburg wrote:
Robert Ramey writes:
I'm doubting that its the complexity of the class.
Sure, I agree. I was just trying to provide more info.
More likely that its the "last" class.
In the tests I am rrunning, each boost unit test is linked with its own main, so no two serialization tests run together. One of those tests fails.
Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this.
All of the individual tests are single threaded (although for build reasons they are linked with the mt libraries). That is, no test creates any additional threads.
You should also run the test with break points set on
~singleton(){ m_is_destroyed = true; // <<< break here }
To verify that this isn't getting called at an unexpected time.
I've done this and the destructor is called 15 times. It isn't obvious to me if this is unexpected (since this could be the base class of a hierarchy of singletons).
Each time it is invoked on a different instance of this. Breakpoints and stack traces are at the end of this message. In the final call to ~singleton the object address is identical to the address of the ~extended_type_info object in the seg fault stack trace.
Note that only the primary thread is ever created. Also, this unit test contains only a single top-level call to the serialization code. Of course, there are nested objects being serialized.
Hope this helps. Let me know if there are more tests I can run.
Thanks,

Have you tested this also on SVN Version? I've had the same/similar problem, and using the SVN Version helped. regards Jens Weller -------- Original-Nachricht --------
Datum: Wed, 08 Oct 2008 13:37:17 -0400 Von: "troy d. straszheim" <troy@resophonic.com> An: boost-users@lists.boost.org Betreff: Re: [Boost-users] serialization 1.36.0 extended_type_info exit issue(s)
Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test
Specifically
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this:
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 90 detail::ktmap::iterator start = x.lower_bound(this); 91 detail::ktmap::iterator end = x.upper_bound(this); 92 assert(start != end); 93 94 // remove entry in map which corresponds to this type 95 do{ 96 if(this == *start) 97 x.erase(start++); 98 else 99 ++start; 100 }while(start != end); 101 } 102 m_key = NULL; 103 }
instead of, say,
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 97 x.erase(this); 101 } 102 m_key = NULL; 103 }
Thanks in advance,
-t
Robert Mecklenburg wrote:
Robert Ramey writes:
I'm doubting that its the complexity of the class.
Sure, I agree. I was just trying to provide more info.
More likely that its the "last" class.
In the tests I am rrunning, each boost unit test is linked with its own main, so no two serialization tests run together. One of those tests fails.
Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this.
All of the individual tests are single threaded (although for build reasons they are linked with the mt libraries). That is, no test creates any additional threads.
You should also run the test with break points set on
~singleton(){ m_is_destroyed = true; // <<< break here }
To verify that this isn't getting called at an unexpected time.
I've done this and the destructor is called 15 times. It isn't obvious to me if this is unexpected (since this could be the base class of a hierarchy of singletons).
Each time it is invoked on a different instance of this. Breakpoints and stack traces are at the end of this message. In the final call to ~singleton the object address is identical to the address of the ~extended_type_info object in the seg fault stack trace.
Note that only the primary thread is ever created. Also, this unit test contains only a single top-level call to the serialization code. Of course, there are nested objects being serialized.
Hope this helps. Let me know if there are more tests I can run.
Thanks,
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger

Jens Weller wrote:
Have you tested this also on SVN Version?
Yeah, same errors. Though as I say it has turned out to be very hard to isolate. -t
I've had the same/similar problem, and using the SVN Version helped.
regards
Jens Weller
-------- Original-Nachricht --------
Datum: Wed, 08 Oct 2008 13:37:17 -0400 Von: "troy d. straszheim" <troy@resophonic.com> An: boost-users@lists.boost.org Betreff: Re: [Boost-users] serialization 1.36.0 extended_type_info exit issue(s)
Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test
Specifically
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this:
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 90 detail::ktmap::iterator start = x.lower_bound(this); 91 detail::ktmap::iterator end = x.upper_bound(this); 92 assert(start != end); 93 94 // remove entry in map which corresponds to this type 95 do{ 96 if(this == *start) 97 x.erase(start++); 98 else 99 ++start; 100 }while(start != end); 101 } 102 m_key = NULL; 103 }
instead of, say,
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 97 x.erase(this); 101 } 102 m_key = NULL; 103 }
Thanks in advance,
-t
Robert Mecklenburg wrote:
Robert Ramey writes:
I'm doubting that its the complexity of the class. Sure, I agree. I was just trying to provide more info.
More likely that its the "last" class. In the tests I am rrunning, each boost unit test is linked with its own main, so no two serialization tests run together. One of those tests fails.
Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this. All of the individual tests are single threaded (although for build reasons they are linked with the mt libraries). That is, no test creates any additional threads.
You should also run the test with break points set on
~singleton(){ m_is_destroyed = true; // <<< break here }
To verify that this isn't getting called at an unexpected time. I've done this and the destructor is called 15 times. It isn't obvious to me if this is unexpected (since this could be the base class of a hierarchy of singletons).
Each time it is invoked on a different instance of this. Breakpoints and stack traces are at the end of this message. In the final call to ~singleton the object address is identical to the address of the ~extended_type_info object in the seg fault stack trace.
Note that only the primary thread is ever created. Also, this unit test contains only a single top-level call to the serialization code. Of course, there are nested objects being serialized.
Hope this helps. Let me know if there are more tests I can run.
Thanks,
Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hm, I had a similar error, and SVN fixed it in September. But I don't know which Plattform/Compiler you use. -------- Original-Nachricht --------
Datum: Wed, 08 Oct 2008 14:00:18 -0400 Von: "troy d. straszheim" <troy@resophonic.com> An: boost-users@lists.boost.org Betreff: Re: [Boost-users] serialization 1.36.0 extended_type_info exit issue(s)
Jens Weller wrote:
Have you tested this also on SVN Version?
Yeah, same errors. Though as I say it has turned out to be very hard to isolate.
-t
I've had the same/similar problem, and using the SVN Version helped.
regards
Jens Weller
-------- Original-Nachricht --------
Datum: Wed, 08 Oct 2008 13:37:17 -0400 Von: "troy d. straszheim" <troy@resophonic.com> An: boost-users@lists.boost.org Betreff: Re: [Boost-users] serialization 1.36.0 extended_type_info exit issue(s)
Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test
Specifically
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this:
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 90 detail::ktmap::iterator start = x.lower_bound(this); 91 detail::ktmap::iterator end = x.upper_bound(this); 92 assert(start != end); 93 94 // remove entry in map which corresponds to this type 95 do{ 96 if(this == *start) 97 x.erase(start++); 98 else 99 ++start; 100 }while(start != end); 101 } 102 m_key = NULL; 103 }
instead of, say,
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 97 x.erase(this); 101 } 102 m_key = NULL; 103 }
Thanks in advance,
-t
Robert Mecklenburg wrote:
Robert Ramey writes:
I'm doubting that its the complexity of the class. Sure, I agree. I was just trying to provide more info.
More likely that its the "last" class. In the tests I am rrunning, each boost unit test is linked with its own main, so no two serialization tests run together. One of those tests fails.
Also it might be relevant that your using a multicore processor. The library presumes that everything before entering main and after leavnig main is run on a single thread. This seems like a reasonable presumption to me. You might look into this. All of the individual tests are single threaded (although for build reasons they are linked with the mt libraries). That is, no test creates any additional threads.
You should also run the test with break points set on
~singleton(){ m_is_destroyed = true; // <<< break here }
To verify that this isn't getting called at an unexpected time. I've done this and the destructor is called 15 times. It isn't obvious to me if this is unexpected (since this could be the base class of a hierarchy of singletons).
Each time it is invoked on a different instance of this. Breakpoints and stack traces are at the end of this message. In the final call to ~singleton the object address is identical to the address of the ~extended_type_info object in the seg fault stack trace.
Note that only the primary thread is ever created. Also, this unit test contains only a single top-level call to the serialization code. Of course, there are nested objects being serialized.
Hope this helps. Let me know if there are more tests I can run.
Thanks,
Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- GMX Kostenlose Spiele: Einfach online spielen und Spaß haben mit Pastry Passion! http://games.entertainment.gmx.net/de/entertainment/games/free/puzzle/616919...

troy d. straszheim wrote:
Jens Weller wrote:
Have you tested this also on SVN Version?
Yeah, same errors. Though as I say it has turned out to be very hard to isolate.
Just to recap. a) when an eti (extended_type_info) is created an entry containing its address is added to a global registry. b) when an eti record is destroyed, all entries in the global registry which correspond to this same object (by matching address) are erased. c) The global registry consists of two collections. d) The problem is occuring when when the eti is being destroyed after the global registry is destroyed. This occurs when global static objects are not destroyed in reverse order that they are created. e) So I added a static boolean flag - is_destroyed to all singleton objects - including the global eti registry. This static flag is set by the destructor of the singleton. f) Any time an eti record is destroyed, it checks the "is_destroyed" flag of each global registry and skips the erase operation if the global registry has been destroyed. So - if this is not working for anyone, one of the following must be true: a) you don't have the lastest copy.(possible) b) the code is multi-threading and has a race condition after main() returns.(seems very unlikely to me) c) my implemenation is flawed(possible - but that's why you testers get the big bucks!) So - which is it? Robert Ramey

Robert Ramey wrote:
Just to recap.
(snip)
a) you don't have the lastest copy.(possible)
I definitely have svn trunk.
b) the code is multi-threading and has a race condition after main() returns.(seems very unlikely to me)
This is all singlethreaded, debug build.
c) my implemenation is flawed(possible - but that's why you testers get the big bucks!)
Would that it were so. I'll go back and look at all this again with one eye on your recap (thanks). In case this knocks anything loose, here's the smallest test case I can produce at the moment. Classes Base and Derived1 live in a shared library, and a Main.o links to it: --------------------- Objects.hpp -------------------------- #ifndef OBJECTS_HPP_INCLUDED #define OBJECTS_HPP_INCLUDED struct Base { int b; virtual ~Base(); Base(int); template <typename Archive> void serialize(Archive& ar, unsigned); }; struct Derived1 : Base { int d1; ~Derived1(); Derived1(int, int); template <typename Archive> void serialize(Archive& ar, unsigned); }; #endif ---------------------- Objects.cpp ----------------------------- #include "Objects.hpp" #include <boost/serialization/export.hpp> #include <boost/serialization/nvp.hpp> #include <boost/serialization/base_object.hpp> #include <boost/archive/xml_oarchive.hpp> namespace bs = boost::serialization; Base::Base(int i) : b(i) { } Base::~Base() { } template <typename Archive> void Base::serialize(Archive& ar, unsigned) { ar & bs::make_nvp("b", b); } template void Base::serialize(boost::archive::xml_oarchive&, unsigned); Derived1::Derived1(int i, int j) : d1(i) , Base(j) { } Derived1::~Derived1() { } template <typename Archive> void Derived1::serialize(Archive& ar, unsigned) { ar & bs::make_nvp("base", bs::base_object<Base>(*this)); ar & bs::make_nvp("d1", d1); } template void Derived1::serialize(boost::archive::xml_oarchive&, unsigned); BOOST_CLASS_EXPORT(Derived1) ------------------------ (end) ------------------------- Here is the Main.cpp, which is compiled to a .o and then linked against the .so: ------------------------- Main.cpp ------------------------- #include <boost/shared_ptr.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/nvp.hpp> #include <boost/archive/xml_oarchive.hpp> #include "Objects.hpp" int main(int argc, char** argv) { boost::archive::xml_oarchive xoa(std::cout); Derived1 d1(9999,8888); xoa & boost::serialization::make_nvp("d1", d1); } ------------------------------------------------------------- Now, this doesn't crash unless you run it under valgrind and have valgrind paint free'd memory with 0xAAAAAAA: % make rm -f *.o *.so gcc -g -I. -I/home/troy/Projects/boost/trunk -c Objects.cpp gcc -shared -o libshlib.so Objects.o -L/home/troy/Projects/boost/trunk/lib -lboost_serialization-d -lstdc++ -Wl,-rpath,/home/troy/Projects/boost/trunk/lib gcc -g -I. -I/home/troy/Projects/boost/trunk -c Main.cpp gcc -o buggy Main.o -L/home/troy/Projects/boost/trunk/lib -lboost_serialization-d -lstdc++ -Wl,-rpath,/home/troy/Projects/boost/trunk/lib -L. -lshlib -Wl,-rpath,`pwd` valgrind --tool=memcheck --free-fill=AA --malloc-fill=BB ./buggy ==11538== Memcheck, a memory error detector. ==11538== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==11538== Using LibVEX rev 1804, a library for dynamic binary translation. ==11538== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==11538== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework. ==11538== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==11538== For more details, rerun with: -v ==11538== <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="5"> <d1 class_id="0" tracking_level="1" version="0" object_id="_0"> <base class_id="1" tracking_level="0" version="0"> <b>8888</b> </base> <d1>9999</d1> </d1> </boost_serialization> ==11538== Invalid read of size 4 ==11538== at 0x410E21B: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_tree.h:1430) ==11538== by 0x410E2AE: std::multiset<boost::serialization::extended_type_info const*, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_multiset.h:436) ==11538== by 0x410D3CC: boost::serialization::extended_type_info::key_unregister() (extended_type_info.cpp:90) ==11538== by 0x410D582: boost::serialization::extended_type_info::~extended_type_info() (extended_type_info.cpp:132) ==11538== by 0x410ECB6: boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0() (extended_type_info_typeid.cpp:74) ==11538== by 0x804DA4F: boost::serialization::extended_type_info_typeid<Derived1>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:83) ==11538== by 0x804CFED: __tcf_1 (singleton.hpp:105) ==11538== by 0x42C5083: exit (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== by 0x42AD457: (below main) (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== Address 0x440d080 is 16 bytes inside a block of size 20 free'd ==11538== at 0x40222EC: operator delete(void*) (vg_replace_malloc.c:342) ==11538== by 0x410DE38: __gnu_cxx::new_allocator<std::_Rb_tree_node<boost::serialization::extended_type_info const*> >::deallocate(std::_Rb_tree_node<boost::serialization::extended_type_info const*>*, unsigned) (new_allocator.h:97) ==11538== by 0x410DE6D: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::_M_put_node(std::_Rb_tree_node<boost::serialization::extended_type_info const*>*) (stl_tree.h:371) ==11538== by 0x410DECD: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::_M_destroy_node(std::_Rb_tree_node<boost::serialization::extended_type_info const*>*) (stl_tree.h:401) ==11538== by 0x410DF23: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::_M_erase(std::_Rb_tree_node<boost::serialization::extended_type_info const*>*) (stl_tree.h:1325) ==11538== by 0x410DF62: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::~_Rb_tree() (stl_tree.h:592) ==11538== by 0x410DFBE: std::multiset<boost::serialization::extended_type_info const*, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::~multiset() (stl_multiset.h:91) ==11538== by 0x410D349: __tcf_0 (singleton.hpp:105) ==11538== by 0x42C53B0: __cxa_finalize (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== by 0x40F7CA2: (within /home/troy/Projects/boost/trunk/lib/libboost_serialization-d.so) ==11538== by 0x413ED0B: (within /home/troy/Projects/boost/trunk/lib/libboost_serialization-d.so) ==11538== by 0x400DFDE: (within /lib/ld-2.7.so) ==11538== ==11538== Invalid read of size 4 ==11538== at 0x40FCD08: boost::serialization::extended_type_info::get_key() const (extended_type_info.hpp:69) ==11538== by 0x410DFE2: boost::serialization::detail::key_compare::operator()(boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*) const (extended_type_info.cpp:46) ==11538== by 0x410E22F: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_tree.h:1430) ==11538== by 0x410E2AE: std::multiset<boost::serialization::extended_type_info const*, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_multiset.h:436) ==11538== by 0x410D3CC: boost::serialization::extended_type_info::key_unregister() (extended_type_info.cpp:90) ==11538== by 0x410D582: boost::serialization::extended_type_info::~extended_type_info() (extended_type_info.cpp:132) ==11538== by 0x410ECB6: boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0() (extended_type_info_typeid.cpp:74) ==11538== by 0x804DA4F: boost::serialization::extended_type_info_typeid<Derived1>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:83) ==11538== by 0x804CFED: __tcf_1 (singleton.hpp:105) ==11538== by 0x42C5083: exit (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== by 0x42AD457: (below main) (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== Address 0xaaaaaab2 is not stack'd, malloc'd or (recently) free'd ==11538== ==11538== Process terminating with default action of signal 11 (SIGSEGV) ==11538== Access not within mapped region at address 0xAAAAAAB2 ==11538== at 0x40FCD08: boost::serialization::extended_type_info::get_key() const (extended_type_info.hpp:69) ==11538== by 0x410DFE2: boost::serialization::detail::key_compare::operator()(boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*) const (extended_type_info.cpp:46) ==11538== by 0x410E22F: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_tree.h:1430) ==11538== by 0x410E2AE: std::multiset<boost::serialization::extended_type_info const*, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> >::lower_bound(boost::serialization::extended_type_info const* const&) (stl_multiset.h:436) ==11538== by 0x410D3CC: boost::serialization::extended_type_info::key_unregister() (extended_type_info.cpp:90) ==11538== by 0x410D582: boost::serialization::extended_type_info::~extended_type_info() (extended_type_info.cpp:132) ==11538== by 0x410ECB6: boost::serialization::detail::extended_type_info_typeid_0::~extended_type_info_typeid_0() (extended_type_info_typeid.cpp:74) ==11538== by 0x804DA4F: boost::serialization::extended_type_info_typeid<Derived1>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:83) ==11538== by 0x804CFED: __tcf_1 (singleton.hpp:105) ==11538== by 0x42C5083: exit (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== by 0x42AD457: (below main) (in /lib/tls/i686/cmov/libc-2.7.so) ==11538== ==11538== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 23 from 1) ==11538== malloc/free: in use at exit: 0 bytes in 0 blocks. ==11538== malloc/free: 25 allocs, 25 frees, 1,265 bytes allocated. ==11538== For counts of detected errors, rerun with: -v ==11538== All heap blocks were freed -- no leaks are possible. make: *** [buggy] Segmentation fault What is really odd is that if you change the Main to serialize through shared-pointer-to-base, things look fine: ------------------ working Main.cpp -------------------------- #include <boost/shared_ptr.hpp> #include <boost/serialization/shared_ptr.hpp> #include <boost/serialization/nvp.hpp> #include <boost/archive/xml_oarchive.hpp> #include "Objects.hpp" int main(int argc, char** argv) { boost::archive::xml_oarchive xoa(std::cout); boost::shared_ptr<Base> bp(new Derived1(777,666)); xoa & boost::serialization::make_nvp("ptr", bp); } --------------------- output of the run ----------------------- % make rm -f *.o *.so gcc -g -I. -I/home/troy/Projects/boost/trunk -c Objects.cpp gcc -shared -o libshlib.so Objects.o -L/home/troy/Projects/boost/trunk/lib -lboost_serialization-d -lstdc++ -Wl,-rpath,/home/troy/Projects/boost/trunk/lib gcc -g -I. -I/home/troy/Projects/boost/trunk -c Main.cpp gcc -o buggy Main.o -L/home/troy/Projects/boost/trunk/lib -lboost_serialization-d -lstdc++ -Wl,-rpath,/home/troy/Projects/boost/trunk/lib -L. -lshlib -Wl,-rpath,`pwd` valgrind --tool=memcheck --free-fill=AA --malloc-fill=BB ./buggy ==11556== Memcheck, a memory error detector. ==11556== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==11556== Using LibVEX rev 1804, a library for dynamic binary translation. ==11556== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==11556== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework. ==11556== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==11556== For more details, rerun with: -v ==11556== <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <!DOCTYPE boost_serialization> <boost_serialization signature="serialization::archive" version="5"> <ptr class_id="0" tracking_level="0" version="1"> <pxvoid boost::archive::detail::basic_oarchive::register_basic_serializer(const boost::archive::detail::basic_oserializer&) class_id="2" class_name="Derived1" tracking_level="1" version="0" object_id="_0"> <base class_id="1" tracking_level="1" version="0" object_id="_1"> <b>666</b> </base> <d1>777</d1> </px> </ptr> </boost_serialization> ==11556== ==11556== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 23 from 1) ==11556== malloc/free: in use at exit: 0 bytes in 0 blocks. ==11556== malloc/free: 32 allocs, 32 frees, 1,409 bytes allocated. ==11556== For counts of detected errors, rerun with: -v ==11556== All heap blocks were freed -- no leaks are possible. ---------------------------------------------------------------- That's all I've got for now... -t

troy d. straszheim wrote:
Robert Ramey wrote:
Just to recap.
(snip)
a) you don't have the lastest copy.(possible)
I definitely have svn trunk.
b) the code is multi-threading and has a race condition after main() returns.(seems very unlikely to me)
This is all singlethreaded, debug build.
c) my implemenation is flawed(possible - but that's why you testers get the big bucks!)
Would that it were so.
Now, this doesn't crash unless you run it under valgrind and have valgrind paint free'd memory with 0xAAAAAAA:
==11538== Invalid read of size 4 ==11538== at 0x410E21B: std::_Rb_tree<boost::serialization::extended_type_info const*, boost::serialization::extended_type_info const*, std::_Identity<boost::serialization::extended_type_info const*>, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> ::lower_bound(boost::serialization::extended_type_info const* const&) (stl_tree.h:1430) ==11538== by 0x410E2AE: std::multiset<boost::serialization::extended_type_info const*, boost::serialization::detail::key_compare, std::allocator<boost::serialization::extended_type_info const*> ::lower_bound(boost::serialization::extended_type_info const* const&) (stl_multiset.h:436) ==11538== by 0x410D3CC: boost::serialization::extended_type_info::key_unregister() (extended_type_info.cpp:90) ==11538== by 0x410D582: boost::serialization::extended_type_info::~extended_type_info()
... Here is the code that provokes the error BOOST_SERIALIZATION_DECL(void) extended_type_info::key_register(const char *key) { assert(NULL != key); m_key = key; singleton<detail::ktmap>::get_mutable_instance().insert(this); } BOOST_SERIALIZATION_DECL(void) extended_type_info::key_unregister() { assert(NULL != m_key); if(! singleton<detail::ktmap>::is_destroyed()){ detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); detail::ktmap::iterator start = x.lower_bound(this); ///////// line # 90 - problem is here detail::ktmap::iterator end = x.upper_bound(this); assert(start != end); // remove entry in map which corresponds to this type do{ if(this == *start) x.erase(start++); else ++start; }while(start != end); } m_key = NULL; } So trap on this line and verify that singleton<detail::ktmap>::is_destroyed() is not true then trap on the destructor of singleton<detail::ktmap>::is_destroyed() to verify that m_is_destroyed is in fact getting set when the table is destroyed. Robert Ramey

Robert Ramey wrote:
So trap on this line and verify that singleton<detail::ktmap>::is_destroyed() is not true
then trap on the destructor of singleton<detail::ktmap>::is_destroyed() to verify that
m_is_destroyed is in fact getting set when the table is destroyed.
The detail::ktmap is getting destroyed *before* the singleton that holds it. So is_destroyed() returns false... but that's wrong. Does the standard guarantee that the static T that is inside singleton<T>::get_instance() will be destroyed *after* the singleton<T> itself? It seems like the compiler could figure out that the singleton<T> never actually talks to the static T inside get_instance(), ie. it looks like it would be pretty easy to figure out that use() doesn't do anything and get rid of it entirely. I put together a fix which works... not sure what I think of it. Singletons inherit from a singleton_instance class that notifies the singleton (!) of its destruction. Looks like this: in extended_type_info.cpp, detail::ktmap is no longer a typedef: struct ktmap : std::multiset<const extended_type_info*, key_compare>, singleton_instance<ktmap> { }; and in singleton.hpp, you've got this: template <class T> class singleton_instance; template <class T> class singleton : public singleton_module { static bool m_is_destroyed; BOOST_DLLEXPORT static T & instance; // include this to provoke instantiation at pre-execution time static void use(T const &) {} BOOST_DLLEXPORT static T & get_instance() { static T t; // refer to instance, causing it to be instantiated (and // initialized at startup on working compilers) assert(! m_is_destroyed); use(instance); return t; } BOOST_DLLEXPORT static void destroy() { m_is_destroyed = true; } public: BOOST_DLLEXPORT static T & get_mutable_instance(){ assert(! is_locked()); return get_instance(); } BOOST_DLLEXPORT static const T & get_const_instance(){ return get_instance(); } BOOST_DLLEXPORT static bool is_destroyed(){ return m_is_destroyed; } ~singleton(){ m_is_destroyed = true; } friend class singleton_instance<T>; }; template<class T> BOOST_DLLEXPORT T & singleton<T>::instance = singleton<T>::get_instance(); template<class T> bool singleton<T>::m_is_destroyed = false; template <class T> class singleton_instance { public: ~singleton_instance() { singleton<T>::destroy(); } }; What do you make of all this? -t

OK - I see the problem now - good work. I'm not sold on your fix but I think this can be addressed. I'll make the patch, test here, and check it into the trunk for testing. Robert Ramey

Robert Ramey wrote:
OK - I see the problem now - good work. I'm not sold on your fix but I think this can be addressed.
I'll make the patch, test here, and check it into the trunk for testing.
OK thanks for the help. Having solved that one, I backported that patch to 1.36.0, expanded my test cases, and we appear to have the same problems at exit with the archive_pointer_oserializers: archive_pointer_oserializer<Archive>::~archive_pointer_oserializer(){ // note: we need to check that the map still exists as we can't depend // on static variables being constructed in a specific sequence if(! serialization::singleton< oserializer_map<Archive> >::is_destroyed() ){ unsigned int count; count = serialization::singleton< oserializer_map<Archive> >::get_mutable_instance().erase(this); assert(count); } } My stacktrace looks like: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb35276c0 (LWP 23136)] 0xb643d56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 (gdb) where #0 0xb643d56b in std::_Rb_tree_rebalance_for_erase () from /usr/lib/libstdc++.so.6 #1 0xb6a8de2d in std::_Rb_tree<boost::archive::detail::basic_serializer const*, boost::archive::detail::basic_serializer const*, std::_Identity<boost::archive::detail::basic_serializer const*>, boost::archive::detail::type_info_pointer_compare, std::allocator<boost::archive::detail::basic_serializer const*> >::erase (this=0xb62f6ec8, __position={_M_node = 0x83b5788}) at /usr/include/c++/4.2/bits/stl_tree.h:1247 #2 0xb6a8df14 in std::_Rb_tree<boost::archive::detail::basic_serializer const*, boost::archive::detail::basic_serializer const*, std::_Identity<boost::archive::detail::basic_serializer const*>, boost::archive::detail::type_info_pointer_compare, std::allocator<boost::archive::detail::basic_serializer const*> >::erase (this=0xb62f6ec8, __first={_M_node = 0x83b5068}, __last= {_M_node = 0x83b5068}) at /usr/include/c++/4.2/bits/stl_tree.h:1340 #3 0xb6a8df85 in std::_Rb_tree<boost::archive::detail::basic_serializer const*, boost::archive::detail::basic_serializer const*, std::_Identity<boost::archive::detail::basic_serializer const*>, boost::archive::detail::type_info_pointer_compare, std::allocator<boost::archive::detail::basic_serializer const*> >::erase (this=0xb62f6ec8, __x=@0xbfc39bbc) at /usr/include/c++/4.2/bits/stl_tree.h:1274 #4 0xb6a8dfc0 in std::set<boost::archive::detail::basic_serializer const*, boost::archive::detail::type_info_pointer_compare, std::allocator<boost::archive::detail::basic_serializer const*> >::erase (this=0xb62f6ec8, __x=@0xbfc39bbc) at /usr/include/c++/4.2/bits/stl_set.h:373 #5 0xb62c7ce6 in ~archive_pointer_oserializer (this=0x82154ac) at /opt/i3/ports/var/db/dports/build/file._opt_i3_ports_var_db_dports_sources_rsync.code.icecube.wisc.edu_icecube-tools-ports_devel_boost_1.36.0/work/boost_1.36.0/boost/archive/impl/archive_pointer_oserializer.ipp:74 #6 0x08120d23 in ~pointer_oserializer (this=0x82154ac) at /opt/i3/ports/include/boost-1.36.0/boost/archive/detail/oserializer.hpp:154 #7 0x0811d7f0 in __tcf_25 () at /opt/i3/ports/include/boost-1.36.0/boost/serialization/singleton.hpp:104 #8 0xb41e6084 in exit () from /lib/tls/i686/cmov/libc.so.6 #9 0xb41ce458 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #10 0x080f4c01 in _start () This was part of the reason for the template approach I submitted... it looks like lots of these singletons will have to be taken care of like this. -t

I've made changes in the trunk to address this problem. Please try to run this test again to verifiy that I've indeed fixed it. Robert Ramey

I've made changes in the trunk to address this problem.
Please try to run this test again to verifiy that I've indeed fixed it.
FWIW, my application now works indeed. It is serializing polymorphic objects for which the BOOST_CLASS_EXPORT is located in dynamically loaded shared libraries. It was crashing in gcc/release mode/linux before. Good job! Regards Hartmut

I'd like to wait one or two more days for trunk test and from Troy then merge this change into the release. If its not too late. Robert Ramey Hartmut Kaiser wrote:
I've made changes in the trunk to address this problem.
Please try to run this test again to verifiy that I've indeed fixed it.
FWIW, my application now works indeed. It is serializing polymorphic objects for which the BOOST_CLASS_EXPORT is located in dynamically loaded shared libraries. It was crashing in gcc/release mode/linux before.
Good job! Regards Hartmut

On the trunk things look good to me. Valgrind shows things as clean, no crashes on exit. BTW we also have BOOST_CLASS_EXPORT in dynamically loaded libraries, (hundreds of them in tens of libraries) and I see no problems at all. Thanks as always for your help on all this. -t Robert Ramey wrote:
I'd like to wait one or two more days for trunk test and from Troy then merge this change into the release. If its not too late.
Robert Ramey
Hartmut Kaiser wrote:
I've made changes in the trunk to address this problem.
Please try to run this test again to verifiy that I've indeed fixed it. FWIW, my application now works indeed. It is serializing polymorphic objects for which the BOOST_CLASS_EXPORT is located in dynamically loaded shared libraries. It was crashing in gcc/release mode/linux before.
Good job! Regards Hartmut
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

For building Andrey Semashev's boost.log from 2008/10/1 cvs with: bjam --toolset=msvc variant=debug,release threading=multi link=static --with-log define=BOOST_LOG_USE_CHAR stage I find that in formatter_parser.cpp and init_from_stream.cpp, I need to change from: #if !defined(BOOST_MSVC) || _MSC_VER > 1310 friend class log::aux::lazy_singleton< formatters_repository< CharT > >; #else friend class base_type; #endif To: //#if !defined(BOOST_MSVC) || _MSC_VER > 1310 // friend class log::aux::lazy_singleton< formatters_repository< CharT >
; //#else friend class base_type; //#endif
That is to say that the msvc compiler (VS 2005), does not like the log::aux..... line. It also may be useful to update the documentation (http://boost-log.sourceforge.net/libs/log/doc/html/log/installation.html) slightly: 1) put in a link to where the library can be downloaded (I used http://sourceforge.net/cvs/?group_id=199644 for cvs) 2) indicate that the cvs subdirectory /boost-log/boost/log should be placed in boost_x_xx_x/boost/ 3) indicate that the cvs subdirectory /boost-log/libs/log should be placed in boost_x_xx_x/libs/ 4) If one uses a define such as BOOST_LOG_USE_CHAR in the 'bjam', does one also need to include it as a define in user code, or is somehow automagically applied to user code? What does it default to if neither BOOST_LOG_USE_CHAR or BOOST_LOG_USE_WCHAR_T are used? What should be used if user code is being compiled with out unicode? -- Scanned for viruses and dangerous content at http://www.oneunified.net and is believed to be clean.

Robert Ramey writes:
I've made changes in the trunk to address this problem.
Please try to run this test again to verifiy that I've indeed fixed it.
I've just checked the head of the trunk and all my serialization tests now pass. Thanks to everyone involved for fixing this issue. Cheers, -- Robert p.s. As a (trivial?) asside would it be reasonable to apply the following patch to avoid compilation warnings on gcc? Index: boost/serialization/extended_type_info_typeid.hpp =================================================================== --- boost/serialization/extended_type_info_typeid.hpp (revision 49317) +++ boost/serialization/extended_type_info_typeid.hpp (working copy) @@ -112,7 +112,7 @@ return NULL; } } - void destroy(void const * const p) const { + void destroy(void const * const /* p */) const { // the only current usage of extended type info is in the // serialization library. The statement below requires // that destructor of type T be public and this creates

I don't understand why the extended type info should be static/global. Why not provide something like: namespace boost { class extended_type_info_storage; shared_ptr<extended_type_info_storage> serialization_init(); } We can require that this function is called prior to any other serialization library function, and that the extended_type_info_storage object is afloat while the serialization library is in use. If the user wants to make the returned shared_ptr a static/global object (and deal with all the problems being discussed in this thread) they can certainly do so -- but we won't have to support them. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
We can require that this function is called prior to any other serialization library function, and that the extended_type_info_storage object is afloat while the serialization library is in use.
Such a requirement was considered unacceptable for a number of reviewers. The basic argument against it was that it wouldn't work with "plug-in" type code where the main progam needs to be able o dynamically load types which were not defined at the time the main code was written. The library does provide a simple portable solution for those willing to specify the types they expect to use before they are serialized. This seems similar in effect to what you propose. Robert Ramey

Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test
Specifically
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this:
In my experience this happens whenever you BOOST_CLASS_EXPORT() a specific type more than once. Regards Hartmut

Hartmut Kaiser wrote:
Robert Mecklenburg, I'd be interested to see what you get from
In my experience this happens whenever you BOOST_CLASS_EXPORT() a specific type more than once.
Hmmm - maybe in the past, but is this still true?
Regards Hartmut

Hartmut Kaiser wrote:
Robert Mecklenburg, I'd be interested to see what you get from
In my experience this happens whenever you BOOST_CLASS_EXPORT() a specific type more than once.
Hmmm - maybe in the past, but is this still true?
True for V1.36 Regards Hartmut

Hartmut Kaiser wrote:
Hartmut Kaiser wrote:
Robert Mecklenburg, I'd be interested to see what you get from
In my experience this happens whenever you BOOST_CLASS_EXPORT() a specific type more than once.
Hmmm - maybe in the past, but is this still true?
True for V1.36
Regards Hartmut
Actually its a new problem in V1.36. I meant if it was still true in the trunk Robert Ramey

troy d. straszheim writes:
Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test
Interesting. Today when I link and run the program it runs without a crash (although my actuall tests still crash). It seems to have something to do with the contents of freed memory (which may explain why it doesn't crash at this moment). Valgrind shows invalid memory read and delete below: 509 rmecklenburg:common$ valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./serial ==32298== Memcheck, a memory error detector. ==32298== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==32298== Using LibVEX rev 1804, a library for dynamic binary translation. ==32298== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==32298== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework. ==32298== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==32298== For more details, rerun with: -v ==32298== Running 1 test case... *** No errors detected ==32298== Invalid read of size 4 ==32298== at 0x40B793F: boost::unit_test::framework_impl::~framework_impl() (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40B4BDF: (within /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x425C103: exit (exit.c:75) ==32298== by 0x4245457: (below main) (libc-start.c:252) ==32298== Address 0x438ae3c is 20 bytes inside a block of size 24 free'd ==32298== at 0x40232EC: operator delete(void*) (vg_replace_malloc.c:342) ==32298== by 0x40B7526: std::_Rb_tree<unsigned long, std::pair<unsigned long const, boost::unit_test::test_unit*>, std::_Select1st<std::pair<unsigned long const, boost::unit_test::test_unit*> >, std::less<unsigned long>, std::allocator<std::pair<unsigned long const, boost::unit_test::test_unit*> > >::erase(unsigned long const&) (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40B497B: boost::unit_test::framework::deregister_test_unit(boost::unit_test::test_unit*) (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40CE37E: boost::unit_test::test_unit::~test_unit() (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40B793B: boost::unit_test::framework_impl::~framework_impl() (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40B4BDF: (within /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x425C103: exit (exit.c:75) ==32298== by 0x4245457: (below main) (libc-start.c:252) ==32298== ==32298== Invalid free() / delete / delete[] ==32298== at 0x40232EC: operator delete(void*) (vg_replace_malloc.c:342) ==32298== by 0x40B7949: boost::unit_test::framework_impl::~framework_impl() (in /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x40B4BDF: (within /home/mecklen/work/boost-install/lib/boost-1_37/libboost_unit_test_framework-gcc42-mt-1_37.so.1.37.0) ==32298== by 0x425C103: exit (exit.c:75) ==32298== by 0x4245457: (below main) (libc-start.c:252) ==32298== Address 0xeeeeeeee is not stack'd, malloc'd or (recently) free'd ==32298== ==32298== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 25 from 1) ==32298== malloc/free: in use at exit: 52 bytes in 1 blocks. ==32298== malloc/free: 112 allocs, 112 frees, 37,564 bytes allocated. ==32298== For counts of detected errors, rerun with: -v ==32298== searching for pointers to 1 not-freed blocks. ==32298== checked 146,152 bytes. ==32298== ==32298== LEAK SUMMARY: ==32298== definitely lost: 52 bytes in 1 blocks. ==32298== possibly lost: 0 bytes in 0 blocks. ==32298== still reachable: 0 bytes in 0 blocks. ==32298== suppressed: 0 bytes in 0 blocks. ==32298== Rerun with --leak-check=full to see details of leaked memory. Here is one of my "real" test that does crash today: -*- mode: compilation; default-directory: "~/s5w/trunk/core/common/" -*- Compilation started at Wed Oct 8 14:43:20 valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE src/test/SampleBinTest --catch_system_errors=no ==1235== Memcheck, a memory error detector. ==1235== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==1235== Using LibVEX rev 1804, a library for dynamic binary translation. ==1235== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==1235== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework. ==1235== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==1235== For more details, rerun with: -v ==1235== ==1235== Syscall param sigaltstack(ss) points to uninitialised byte(s) ==1235== at 0x4929B21: sigaltstack (in /usr/lib/debug/libc-2.7.so) ==1235== by 0x403F5E6: boost::execution_monitor::catch_signals(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x403F6A4: boost::execution_monitor::execute(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4046103: boost::unit_test::framework::init(bool (*)(), int, char**) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4053B3C: boost::unit_test::unit_test_main(bool (*)(), int, char**) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x808BE3D: main (unit_test.hpp:59) ==1235== Address 0xbeb71a50 is on thread 1's stack ==1235== ==1235== Syscall param sigaltstack(ss) points to uninitialised byte(s) ==1235== at 0x4929B21: sigaltstack (in /usr/lib/debug/libc-2.7.so) ==1235== by 0x403F5E6: boost::execution_monitor::catch_signals(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x403F6A4: boost::execution_monitor::execute(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x404522D: boost::unit_test::framework::run(unsigned long, bool) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4053BF8: boost::unit_test::unit_test_main(bool (*)(), int, char**) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x808BE3D: main (unit_test.hpp:59) ==1235== Address 0xbeb71820 is on thread 1's stack Running 5 test cases... ==1235== ==1235== Syscall param sigaltstack(ss) points to uninitialised byte(s) ==1235== at 0x4929B21: sigaltstack (in /usr/lib/debug/libc-2.7.so) ==1235== by 0x403F5E6: boost::execution_monitor::catch_signals(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x403F6A4: boost::execution_monitor::execute(boost::unit_test::callback0<int> const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x40559FA: boost::unit_test::unit_test_monitor_t::execute_and_translate(boost::unit_test::test_case const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x404740E: boost::unit_test::framework_impl::visit(boost::unit_test::test_case const&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x405D27E: boost::unit_test::traverse_test_tree(boost::unit_test::test_case const&, boost::unit_test::test_tree_visitor&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x405E0AF: boost::unit_test::traverse_test_tree(unsigned long, boost::unit_test::test_tree_visitor&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x405DEF2: boost::unit_test::traverse_test_tree(boost::unit_test::test_suite const&, boost::unit_test::test_tree_visitor&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x405E0E4: boost::unit_test::traverse_test_tree(unsigned long, boost::unit_test::test_tree_visitor&) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4045592: boost::unit_test::framework::run(unsigned long, bool) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4053BF8: boost::unit_test::unit_test_main(bool (*)(), int, char**) (in /usr/lib/boost-1_36/libboost_unit_test_framework-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x808BE3D: main (unit_test.hpp:59) ==1235== Address 0xbeb71700 is on thread 1's stack *** No errors detected ==1235== ==1235== Invalid read of size 4 ==1235== at 0x44E3839: boost::serialization::detail::extended_type_info_typeid_0::type_unregister() (in /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x8083803: boost::serialization::extended_type_info_typeid<s5w::SampleBin>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:80) ==1235== by 0x807A705: __tcf_6 (singleton.hpp:104) ==1235== by 0x492C103: exit (exit.c:75) ==1235== by 0x4915457: (below main) (libc-start.c:252) ==1235== Address 0x4bbbc58 is 16 bytes inside a block of size 20 free'd ==1235== at 0x40232EC: operator delete(void*) (vg_replace_malloc.c:342) ==1235== by 0x44E34C6: (within /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x492C437: __cxa_finalize (cxa_finalize.c:56) ==1235== by 0x44D4622: (within /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x4502C2B: (within /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x400DFCE: _dl_fini (in /lib/ld-2.7.so) ==1235== by 0x492C103: exit (exit.c:75) ==1235== by 0x4915457: (below main) (libc-start.c:252) ==1235== ==1235== Invalid read of size 4 ==1235== at 0x44E383F: boost::serialization::detail::extended_type_info_typeid_0::type_unregister() (in /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x8083803: boost::serialization::extended_type_info_typeid<s5w::SampleBin>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:80) ==1235== by 0x807A705: __tcf_6 (singleton.hpp:104) ==1235== by 0x492C103: exit (exit.c:75) ==1235== by 0x4915457: (below main) (libc-start.c:252) ==1235== Address 0xeeeeeeee is not stack'd, malloc'd or (recently) free'd ==1235== ==1235== Process terminating with default action of signal 11 (SIGSEGV) ==1235== Access not within mapped region at address 0xEEEEEEEE ==1235== at 0x44E383F: boost::serialization::detail::extended_type_info_typeid_0::type_unregister() (in /usr/lib/boost-1_36/libboost_serialization-gcc42-mt-1_36.so.1.36.0) ==1235== by 0x8083803: boost::serialization::extended_type_info_typeid<s5w::SampleBin>::~extended_type_info_typeid() (extended_type_info_typeid.hpp:80) ==1235== by 0x807A705: __tcf_6 (singleton.hpp:104) ==1235== by 0x492C103: exit (exit.c:75) ==1235== by 0x4915457: (below main) (libc-start.c:252) ==1235== ==1235== ERROR SUMMARY: 18 errors from 5 contexts (suppressed: 51 from 1) ==1235== malloc/free: in use at exit: 2,672 bytes in 8 blocks. ==1235== malloc/free: 2,328 allocs, 2,320 frees, 479,988 bytes allocated. ==1235== For counts of detected errors, rerun with: -v ==1235== searching for pointers to 8 not-freed blocks. ==1235== checked 484,704 bytes. ==1235== ==1235== LEAK SUMMARY: ==1235== definitely lost: 0 bytes in 0 blocks. ==1235== possibly lost: 0 bytes in 0 blocks. ==1235== still reachable: 2,672 bytes in 8 blocks. ==1235== suppressed: 0 bytes in 0 blocks. ==1235== Rerun with --leak-check=full to see details of leaked memory. Compilation segmentation fault at Wed Oct 8 14:43:25
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
No, I haven't been able to do that yet. Thanks for any insights, -- Robert

troy d. straszheim wrote:
Robert Mecklenburg, I'd be interested to see what you get from running your tests under valgrind like this:
valgrind --tool=memcheck --malloc-fill=FF --free-fill=EE ./my_failing_test Specifically
- what happens while all the global statics are being destroyed - Can you get a test that passes when run 'normally' to fail when run under valgrind as above?
I've been chasing this for a few days and it just got away from me for the third or fourth time. It looks like there are some double-deletes around and I wouldn't be surprised if it were a compiler or std library bug. I can come up with one only one (lame) question so far... why are the key_unregister methods of the extended_type_info classes written like this:
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 90 detail::ktmap::iterator start = x.lower_bound(this); 91 detail::ktmap::iterator end = x.upper_bound(this); 92 assert(start != end); 93 94 // remove entry in map which corresponds to this type 95 do{ 96 if(this == *start) 97 x.erase(start++); 98 else 99 ++start; 100 }while(start != end); 101 } 102 m_key = NULL; 103 }
instead of, say,
85 BOOST_SERIALIZATION_DECL(void) 86 extended_type_info::key_unregister() { 87 assert(NULL != m_key); 88 if(! singleton<detail::ktmap>::is_destroyed()){ 89 detail::ktmap & x = singleton<detail::ktmap>::get_mutable_instance(); 97 x.erase(this); 101 } 102 m_key = NULL; 103 }
It is possible for the same type to be in the registry more than once. This can occur when code for a serializable type is loaded in a DLL. When the DLL unloads, it takes its code with it. So vtable displatch won't work any more and will crash if used. So its important to remove the member which correponds to the exact extended_type_info record being destroyed. Erasing just one which matches the current type is not enough. Robert Ramey
participants (9)
-
Emil Dotchevski
-
Hartmut Kaiser
-
Jens Weller
-
Ken Roser
-
Ray Burkholder
-
Robert Mecklenburg
-
Robert Ramey
-
Tim St. Clair
-
troy d. straszheim