Opened 6 years ago

Closed 6 years ago

Last modified 5 years ago

#12441 closed Bugs (invalid)

Crash in Boost.Test 1.61

Reported by: Andy Salnikov <a_salnikov@…> Owned by: Gennadiy Rozental
Milestone: To Be Determined Component: test
Version: Boost 1.61.0 Severity: Showstopper
Keywords: Cc:

Description

We have switched from boost 1.59 to 1.61 and I observe strange crashes when trying to run unit tests. I manage to reproduce it with a trivial example which has no used-added code, only Boost.Test stuff. This is observed with g++ 4.9.3 on Scientific Linux 6 with glibc 2.12.

Here is an example:

% cat unit_test.cc 
#define BOOST_TEST_MODULE UnitTest
#include <boost/test/included/unit_test.hpp>

BOOST_AUTO_TEST_CASE(Test1)
{
}

% g++ --version           
g++ (GCC) 4.9.3

% BOO=/path/to/boost/1.61.0
% g++ -std=c++11 -o unit_test -fPIC unit_test.cc -I$BOO/include/boost-1_61 -L$BOO/lib -lboost_unit_test_framework-gcc49-mt-1_61 -lboost_timer-gcc49-mt-1_61 -lboost_system-gcc49-mt-1_61 -lboost_chrono-gcc49-mt-1_61 -Wl,--rpath=$BOO/lib

% ./unit_test 
Running 1 test case...

*** No errors detected
*** glibc detected *** ./unit_test: double free or corruption (!prev): 0x0000000001ca4c70 ***
======= Backtrace: =========
/lib64/libc.so.6[0x33cfe75f3e]
/lib64/libc.so.6[0x33cfe78dd0]
/lib64/libc.so.6(__cxa_finalize+0x9d)[0x33cfe35e7d]
/afs/cern.ch/sw/lcg/releases/LCG_85/Boost/1.61.0/x86_64-slc6-gcc49-opt//lib/libboost_unit_test_framework-gcc49-mt-1_61.so.1.61.0(+0x3b046)[0x7feba3c17046]
======= Memory map: ========
...................

Change History (6)

comment:1 by Andy Salnikov <a_salnikov@…>, 6 years ago

I did some debugging and I think this is caused by double-delete of some global objects, in particular global strings defined in unit_test_parameters.ipp file such as boost::unit_test::runtime_config::HELP. That file is included in other places and it is compiled into libboost_unit_test_framework.so and also into application object file. This causes constructor of thaose global object being called twice, once from libboost_unit_test_framework.so globals initialization, and once from application globals initialization. This also causes destructor of these objects called twice during global destruction.

I'm not sure whether this is issue specific to g++ version or glibc version, I'm not sure why this issue was not discovered by anybody yet.

comment:2 by anonymous, 6 years ago

Component: Nonetest
Owner: set to Gennadiy Rozental

comment:3 by Andy Salnikov <a_salnikov@…>, 6 years ago

I made another test with the same code (above) on different platform:

  • boost 1.60
  • CentOS 7
  • gcc 4.8.5

With this setup instead of glibc complaints I see SEGV crash, stack from this crash:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff69b8aad in malloc_consolidate () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff69b8aad in malloc_consolidate () from /lib64/libc.so.6
#1  0x00007ffff69b9ec6 in _int_free () from /lib64/libc.so.6
#2  0x0000000000476c92 in void boost::checked_array_delete<char>(char*) ()
#3  0x00000000004697c9 in boost::scoped_array<char>::~scoped_array() ()
#4  0x00000000004596fa in boost::execution_monitor::~execution_monitor() ()
#5  0x00000000004697e4 in boost::unit_test::unit_test_monitor_t::~unit_test_monitor_t() ()
#6  0x00007ffff69761da in __cxa_finalize () from /lib64/libc.so.6
#7  0x00007ffff7b6db63 in __do_global_dtors_aux () from /u2/salnikov/lsstsw/stack/Linux64/boost/1.60.lsst1/lib/libboost_unit_test_framework.so.1.60.0
#8  0x00007fffffffdd70 in ?? ()
#9  0x00007ffff7deaa1a in _dl_fini () from /lib64/ld-linux-x86-64.so.2

which looks pretty much the same globals destruction issue, except his happens not is string destructors but in some scoped array destructor.

comment:4 by Andy Salnikov <a_salnikov@…>, 6 years ago

Sorry, I think this is my own fault. Our build system has migrated to a different setup and new build rules started adding -lboost_unit_test_framework to the link and we did not have #define BOOST_TEST_DYN_LINK in our tests. I should have compared it to what our old build system did, instead I wasted my own and everyone's time trying to debug it. The answer is of course that we should not do -lboost_unit_test_framework without BOOST_TEST_DYN_LINK which is clear if one reads documentation. Sorry again, this can be closed.

comment:5 by Raffi Enficiaud, 6 years ago

Resolution: invalid
Status: newclosed

Great, thanks for having invested time in tracking this down. I'm closing the ticket then.

comment:6 by erenon2@…, 5 years ago

It also happens if one source file assumes dynamically linked boost test:

#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

while the other assumes header-only boost test:

#include <boost/test/included/unit_test.hpp>

It is easy to make such a mistake and really hard to figure out the reason. I'm posting to raise awareness.

Note: See TracTickets for help on using tickets.