strange "fatal errors" with Boost.Test

Dear boost experts, while adding regression tests to my project I experience very strange errors. I am using boost 1.40 and g++ 4.4 as packaged in Debian testing. The problem is that a very simple test suite, one which does almost nothing, produces the following runtime error: ################################################################ cwg@argo:/tmp/lg-bug$ ./test_all Running 1 test case... unknown location(0): fatal error in "sq_dist": signal: illegal operand; address of failing instruction: 0x00410106 *** 1 failure detected in test suite "lg" ################################################################ A quite minimal program which allows me to reproduce the bug is available from http://ilorentz.org/~cwg/lg-bug.tar.gz This is how I can reproduce it on any of my two Debian testing systems. The problem does not appear on an Ubuntu system to which I have access (with boost 1.38, but I do not think that this problem is specific to some boost version). ################################################################ cwg@argo:/tmp$ wget -q http://ilorentz.org/~cwg/lg-bug.tar.gz cwg@argo:/tmp$ tar xfz lg-bug.tar.gz cwg@argo:/tmp$ cd lg-bug/ cwg@argo:/tmp/lg-bug$ g++ -g -o test_all test_glass.cc glass.cc cwg@argo:/tmp/lg-bug$ gdb test_all GNU gdb (GDB) 7.0.1-debian Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /tmp/lg-bug/test_all...done. (gdb) run Starting program: /tmp/lg-bug/test_all Running 1 test case... Program received signal SIGILL, Illegal instruction. 0x0000000000410106 in boost::itest::expectations_logger::data_flow (this=Cannot access memory at address 0x3fdffffffffffe38 ) at /usr/include/boost/test/impl/logged_expectations.ipp:188 188 BOOST_CHECK_EQUAL( *tit, DATA_SIG ); ++tit; (gdb) bt #0 0x0000000000410106 in boost::itest::expectations_logger::data_flow (this=Cannot access memory at address 0x3fdffffffffffe38 ) at /usr/include/boost/test/impl/logged_expectations.ipp:188 Cannot access memory at address 0x3fe0000000000008 ################################################################ The test case (file test_glass.cc) is just: ################################################################ #define BOOST_TEST_MODULE lg #include <boost/test/included/unit_test.hpp> #include "defs.hh" #include "glass.hh" BOOST_AUTO_TEST_CASE(sq_dist) { Levy::Vecd a(2, 1); Levy::Glass sys(Levy::Vecd(1, 1), Levy::Vecb(true, true)); } ################################################################ The two constructors in the body of the testcase do not really do anything except initializing a few numbers and std::vectors. However, the bug disappears when I comment out one of these lines. The backtrace (see log) is not really helpful to me... This is the backtrace of the problem as it appears in my full program: ################################################################ Program received signal SIGSEGV, Segmentation fault. 0x0000000000432728 in ~lazy_ostream_impl (this=0xffffccc0, __in_chrg=<value optimized out>) at /usr/include/boost/test/utils/lazy_ostream.hpp:64 64 class lazy_ostream_impl : public lazy_ostream { (gdb) bt #0 0x0000000000432728 in ~lazy_ostream_impl (this=0xffffccc0, __in_chrg=<value optimized out>) at /usr/include/boost/test/utils/lazy_ostream.hpp:64 #1 0x000000000041010f in expectations_logger (this=0x6f3730, log_file_name=..., test_or_log=false) at /usr/include/boost/test/impl/logged_expectations.ipp:87 #2 0x0000000000475c66 in boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (*)()> (this=0x7fffffffceaf, f=@0x6f2a08) at /usr/include/boost/test/utils/callback.hpp:56 #3 0x00000000004718e5 in boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()>::invoke (this=0x6f2a00) at /usr/include/boost/test/utils/callback.hpp:89 #4 0x000000000043b773 in boost::unit_test::callback0<boost::unit_test::ut_detail::unused>::operator() (this=0x6f2ad0) at /usr/include/boost/test/utils/callback.hpp:118 #5 0x000000000042ec4f in operator() (this=0x6f7378) at /usr/include/boost/test/impl/unit_test_monitor.ipp:41 #6 0x000000000042ec32 in invoke<boost::unit_test::<unnamed>::zero_return_wrapper_t<boost::unit_test::callback0<boost::unit_test::ut_detail::unused> > > (this=0x7fffffffcf3f, f=...) at /usr/include/boost/test/utils/callback.hpp:42 #7 0x000000000042ec13 in invoke (this=0x6f7370) at /usr/include/boost/test/utils/callback.hpp:89 #8 0x0000000000443257 in boost::unit_test::callback0<int>::operator() (this=0x7fffffffdb60) at /usr/include/boost/test/utils/callback.hpp:118 #9 0x000000000043b872 in boost::detail::do_invoke<boost::scoped_ptr<boost::detail::translate_exception_base>, boost::unit_test::callback0<int> > (tr=..., F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:244 #10 0x000000000040f156 in boost::execution_monitor::catch_signals (this=0x6f1d00, F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:956 #11 0x000000000040f21a in boost::execution_monitor::execute (this=0x6f1d00, F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:1282 #12 0x0000000000418eee in boost::unit_test::unit_test_monitor_t::execute_and_translate (this=0x6f1d00, tc=...) at /usr/include/boost/test/impl/unit_test_monitor.ipp:69 #13 0x00000000004311ee in boost::unit_test::framework_impl::visit (this=0x6f1340, tc=...) at /usr/include/boost/test/impl/framework.ipp:150 #14 0x000000000041d587 in boost::unit_test::traverse_test_tree (tc=..., V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:193 #15 0x000000000041daff in boost::unit_test::traverse_test_tree (id=65536, V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:232 #16 0x000000000041d748 in boost::unit_test::traverse_test_tree (suite=..., V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:207 #17 0x000000000041db1c in boost::unit_test::traverse_test_tree (id=1, V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:234 #18 0x000000000040ab87 in boost::unit_test::framework::run (id=1, continue_test=true) at /usr/include/boost/test/impl/framework.ipp:436 #19 0x0000000000418c5c in boost::unit_test::unit_test_main (init_func=0x41eed8 <init_unit_test_suite(int, char**)>, argc=1, argv=0x7fffffffe378) at /usr/include/boost/test/impl/unit_test_main.ipp:185 #20 0x0000000000418e56 in main (argc=1, argv=0x7fffffffe378) at /usr/include/boost/test/impl/unit_test_main.ipp:237 ################################################################ When I add change some irrelevant code the program which just shifts everything a bit the backtrace becomes different or the error disappears. So it looks like some memory corruption problem. But I'm clueless... Thank you in advance for any hints Christoph

Christoph Groth <cwg <at> falma.de> writes:
Dear boost experts,
while adding regression tests to my project I experience very strange errors. I am using boost 1.40 and g++ 4.4 as packaged in Debian testing.
Program received signal SIGILL, Illegal instruction. 0x0000000000410106 in boost::itest::expectations_logger::data_flow
(this=Cannot access memory at
address 0x3fdffffffffffe38 ) at /usr/include/boost/test/impl/logged_expectations.ipp:188 188 BOOST_CHECK_EQUAL( *tit, DATA_SIG ); ++tit; (gdb) bt #0 0x0000000000410106 in boost::itest::expectations_logger::data_flow (this=Cannot access memory at address 0x3fdffffffffffe38 ) at /usr/include/boost/test/impl/logged_expectations.ipp:188 Cannot access memory at address 0x3fe0000000000008 ################################################################
The test case (file test_glass.cc) is just: ################################################################ #define BOOST_TEST_MODULE lg #include <boost/test/included/unit_test.hpp>
#include "defs.hh" #include "glass.hh"
BOOST_AUTO_TEST_CASE(sq_dist) { Levy::Vecd a(2, 1); Levy::Glass sys(Levy::Vecd(1, 1), Levy::Vecb(true, true)); }
This makes no sense. Your test program does not refer to the itest facilities. There is single testing tool involved as well. Something seriously screwing up the stack. Can you try to go step by step in the debugger? Can you also try build UTF as external library? Gennadiy

Gennadiy Rozental <rogeeff@gmail.com> writes:
This makes no sense. Your test program does not refer to the itest facilities. There is single testing tool involved as well. Something seriously screwing up the stack.
Can you try to go step by step in the debugger?
I did. The stack gets corrupted when returning from cfc::operator/<double, 2, int> at tiny_vector.hh:182. The stack looks fine and then gets corrupted after one gdb "step". See attached gdb session transmission. I cannot imagine how this trivial function could corrupt the stack. How to debug this in more detail? I tried objdump -tD test_all >test_all.dis but I cannot find in test_all.dis the addresses mentioned in the traceback (e.g. 0x000000000047d43f)
Can you also try build UTF as external library?
What would that help? The error also appears when I link dynamically against the library provided in Debian (only the backtrace is less useful). Thanks, Christoph The gdb backtrace: ################################################################ (gdb) br tiny_vector.hh:185 Breakpoint 1 at 0x47d56e: file tiny_vector.hh, line 185. (gdb) run Starting program: /tmp/lg-bug/test_all Running 1 test case... Breakpoint 1, cfc::operator/<double, 2, int> (a=..., b=@0x7fffffffcd8c) at tiny_vector.hh:185 185 return a /= b; (gdb) n 186 } (gdb) p a $1 = {x = {0.5, 0.5}} (gdb) p b $2 = (const int &) @0x7fffffffcd8c: 2 (gdb) bt #0 cfc::operator/<double, 2, int> (a=..., b=@0x7fffffffcd8c) at tiny_vector.hh:186 #1 0x000000000047d43f in Glass (this=0x7fffffffcdc0, _size=..., _periodic=...) at glass.cc:5 #2 0x000000000041d50b in sq_dist::test_method (this=0x7fffffffce6f) at test_glass.cc:10 #3 0x000000000041d489 in sq_dist_invoker () at test_glass.cc:7 #4 0x0000000000474178 in boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (*)()> (this=0x7fffffffcecf, f=@0x6d1a08) at /usr/include/boost/test/utils/callback.hpp:56 #5 0x000000000046fdf7 in boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()>::invoke (this=0x6d1a00) at /usr/include/boost/test/utils/callback.hpp:89 #6 0x0000000000439c85 in boost::unit_test::callback0<boost::unit_test::ut_detail::unused>::operator() (this=0x6d1ad0) at /usr/include/boost/test/utils/callback.hpp:118 #7 0x000000000042d161 in operator() (this=0x6d6378) at /usr/include/boost/test/impl/unit_test_monitor.ipp:41 #8 0x000000000042d144 in invoke<boost::unit_test::<unnamed>::zero_return_wrapper_t<boost::unit_test::callback0<boost::unit_test::ut_detail::unused> > > ( this=0x7fffffffcf5f, f=...) at /usr/include/boost/test/utils/callback.hpp:42 #9 0x000000000042d125 in invoke (this=0x6d6370) at /usr/include/boost/test/utils/callback.hpp:89 #10 0x0000000000441769 in boost::unit_test::callback0<int>::operator() (this=0x7fffffffdb80) at /usr/include/boost/test/utils/callback.hpp:118 #11 0x0000000000439d84 in boost::detail::do_invoke<boost::scoped_ptr<boost::detail::translate_exception_base>, boost::unit_test::callback0<int> > (tr=..., F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:244 #12 0x000000000040d676 in boost::execution_monitor::catch_signals (this=0x6cfe80, F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:956 #13 0x000000000040d73a in boost::execution_monitor::execute (this=0x6cfe80, F=...) at /usr/include/boost/test/impl/execution_monitor.ipp:1282 #14 0x000000000041740e in boost::unit_test::unit_test_monitor_t::execute_and_translate (this=0x6cfe80, tc=...) at /usr/include/boost/test/impl/unit_test_monitor.ipp:69 #15 0x000000000042f700 in boost::unit_test::framework_impl::visit (this=0x6cf4c0, tc=...) at /usr/include/boost/test/impl/framework.ipp:150 #16 0x000000000041baa7 in boost::unit_test::traverse_test_tree (tc=..., V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:193 #17 0x000000000041c01f in boost::unit_test::traverse_test_tree (id=65536, V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:232 #18 0x000000000041bc68 in boost::unit_test::traverse_test_tree (suite=..., V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:207 #19 0x000000000041c03c in boost::unit_test::traverse_test_tree (id=1, V=...) at /usr/include/boost/test/impl/unit_test_suite.ipp:234 #20 0x00000000004090a7 in boost::unit_test::framework::run (id=1, continue_test=true) at /usr/include/boost/test/impl/framework.ipp:436 #21 0x000000000041717c in boost::unit_test::unit_test_main (init_func=0x41d3f8 <init_unit_test_suite(int, char**)>, argc=1, argv=0x7fffffffe398) at /usr/include/boost/test/impl/unit_test_main.ipp:185 #22 0x0000000000417376 in main (argc=1, argv=0x7fffffffe398) at /usr/include/boost/test/impl/unit_test_main.ipp:237 (gdb) s Glass (this=0x7fffffffcdc0, _size=..., _periodic=...) at glass.cc:7 7 } (gdb) bt #0 Glass (this=0x7fffffffcdc0, _size=..., _periodic=...) at glass.cc:7 #1 0x000000000041d50b in sq_dist::test_method (this=0x7fffffffce6f) at test_glass.cc:10 #2 0x0000000000410101 in boost::itest::expectations_logger::data_flow (this=Cannot access memory at address 0x3fdffffffffffe38 ) at /usr/include/boost/test/impl/logged_expectations.ipp:188 Cannot access memory at address 0x3fe0000000000008
participants (2)
-
Christoph Groth
-
Gennadiy Rozental