From: Michael van der Westhuizen (r1mikey_at_[hidden])
Date: 2006-10-27 07:23:28


Hi All,

I've recently found a reproducible regression in Boost.Test while
moving from 1.32.0 to 1.33.1. This regression is apparently present in
the HEAD and 1.34 candidate as well.

I can confirm this problem (and the fix) on HP aC++ 06.12 (ia64), HP
aCC 03.67 (PA-RISC) and Sun Studio 11 (SPARC, with and without
-library=stlport4). According to one of our compiler vendors this is
reproducible on Tru64/Alpha cxx as well.

The fix is to change the test_unit::m_dependencies member (in
boost/test/unit_test_suite.hpp, unit_test_suite_impl.hpp in trunk)
from std::list<test_unit_id> to std::vector<test_unit_id> (yes, I know
that doesn't make a whole lot of sense).

The test case is:

---
#include <boost/test/included/unit_test_framework.hpp>
#include <boost/shared_ptr.hpp>
class DummyTest
  : public boost::unit_test_framework::test_suite
{
public:
    DummyTest() :
      boost::unit_test_framework::test_suite( "DummyTest" ) {}
    void testDummy() { BOOST_CHECK( true ); }
};
boost::unit_test_framework::test_suite *
init_unit_test_suite( int argc, char * argv[] )
{
    boost::unit_test_framework::test_suite * test =
        BOOST_TEST_SUITE( "Test Test Suite" );
    boost::shared_ptr<DummyTest> suite_a( new DummyTest() );
    test->add(
      BOOST_CLASS_TEST_CASE( &DummyTest::testDummy, suite_a ) );
    return test;
}
---
When the test has run, and once in global destructors, the binary
dumps core repeatably.
The stack trace of the crash is:
---
[michael_at_uxcpth05 testtest]$  echo "where" | gdb a.out core
HP gdb 5.4.0 for HP Itanium (32 or 64 bit) and target HP-UX 11.2x.
Copyright 1986 - 2001 Free Software Foundation, Inc.
Hewlett-Packard Wildebeest 5.4.0 (based on GDB) is covered by the
GNU General Public License. Type "show copying" to see the conditions to
change it and/or distribute copies. Type "show warranty" for warranty/support.
..
Core was generated by `a.out'.
Program terminated with signal 11, Segmentation fault.
SEGV_ACCERR - Invalid Permissions for object
#0  inline std::list<unsigned long,std::allocator<unsigned long>
>::erase(std::__rw_list_iter<unsigned long,long,unsigned
long*,unsigned long&>) (
    __it=0x7fffeb14, this=0x4003efe0, No.Identifier_315=0x7fffeb10)
    at /opt/aCC/include_std/list:952
952         (*(_C_link_type
((*((_C_list_iter&)__it)._C_node)._C_prev)))._C_next =
(gdb) #0  inline std::list<unsigned long,std::allocator<unsigned long>
>::erase(std::__rw_list_iter<unsigned long,long,unsigned
long*,unsigned long&>) (
    __it=0x7fffeb14, this=0x4003efe0, No.Identifier_315=0x7fffeb10)
    at /opt/aCC/include_std/list:952
#1  0x40c2440:0 in std::list<unsigned long,std::allocator<unsigned
long> >::erase (No.Identifier_316=0x7fffebd0, this=0x4003efe0,
__first=0x7fffebd4,
    __last=0x7fffebd8) at /opt/aCC/include_std/list:902
#2  0x4051a00:0 in boost::unit_test::test_suite::~test_suite()+0x4d0 ()
---Type <return> to continue, or q <return> to quit---
#3  0x407f620:0 in inline boost::checked_delete<DummyTest>(DummyTest*) (
    x=0x4003efc0)
    at /export/home/michael/newboost/boost_1_33_1/boost/checked_delete.hpp:34
#4  0x407f5b0:1 in boost::detail::sp_counted_impl_p<DummyTest>::dispose (
    this=0x40015a30)
    at /export/home/michael/newboost/boost_1_33_1/boost/detail/sp_counted_impl.hpp:76
#5  0x4080610:0 in
boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,boost::unit_test::ut_detail::user_tc_method_invoker<DummyTest>
>::~callback0_impl_t()+0x160 ()
#6  0x4080b30:0 in inline
boost::checked_delete<boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,boost::unit_test::ut_detail::user_tc_method_invoker<DummyTest>
> >(boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,boost::unit_test::ut_detail::user_tc_method_invoker<DummyTest>
>*) (x=0x40015a50)
    at /export/home/michael/newboost/boost_1_33_1/boost/checked_delete.hpp:34
#7  0x4080ac0:1 in
boost::detail::sp_counted_impl_p<boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,boost::unit_test::ut_detail::user_tc_method_invoker<DummyTest>
> >::dispose (this=0x40015a70)
    at /export/home/michael/newboost/boost_1_33_1/boost/detail/sp_counted_impl.hpp:76
#8  0x40c4150:0 in inline boost::detail::sp_counted_base::release() ()
    at /export/home/michael/newboost/boost_1_33_1/boost/detail/sp_counted_base_n---Type
<return> to continue, or q <return> to quit---t.hpp:79
#9  0x40c40c0:0 in inline boost::detail::shared_count::~shared_count() ()
    at /export/home/michael/newboost/boost_1_33_1/boost/detail/shared_count.hpp:159
#10 0x40c4080:0 in boost::unit_test::test_case::~test_case (this=0x400204d0,
    No.Identifier_326=2)
    at /export/home/michael/newboost/boost_1_33_1/boost/test/unit_test_suite.hpp:108
#11 0x40c4a50:0 in boost::unit_test::test_case::~test_case()+0x30 ()
#12 0x40d6fe0:0 in boost::unit_test::framework_impl::~framework_impl (
    this=0x40012f90, No.Identifier_385=2)
    at /export/home/michael/newboost/boost_1_33_1/boost/test/impl/framework.ipp:78
#13 0x406a570:0 in boost::unit_test::framework_impl::~framework_impl()+0x30 ()
#14 0x60000000c6511f50:0 in __cxa_finalize+0x190 ()
   from /usr/lib/hpux32/libCsup.so.1
#15 0x60000000c6511d70:0 in __cxxTerm_body()+0x30 ()
   from /usr/lib/hpux32/libCsup.so.1
#16 0x60000000c6511c40:0 in __cxxTerm+0x20 () from /usr/lib/hpux32/libCsup.so.1
#17 0x60000000c0282560:0 in __exit_handler+0xa0 ()
   from /usr/lib/hpux32/libc.so.1
---
After applying the fix above the test runs reliably.
It'd be great to have this fix applied to the 1.34.0 candidate and the trunk.
Regards,
Michael