I'm struggling with a mysterious problem. I only see my RHEL4 build. Some of my unit tests (using boost 1.36 unit test framework) fail on RHEL4 (gcc 3.4.6) and use release build type. I do not see a problem using RHEL5 versions for release or debugging (gcc 4.1.2, boost-1.39); and I don't see it on Windows 32-bit or 64-bit using Visual Studio 2005 (using boost-1.36) or 2008 (using boost-1.39).
Suspecting that this might be due to some subtle memory issue, I continued to run valgrind in a test application (the smallest case that saved the problem). Here is what I got when I ran valgrind using the "full, inaccessible" mode:
==12285== Memcheck, a memory error detector. ==12285== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al. ==12285== Using LibVEX rev 1575, a library for dynamic binary translation. ==12285== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP. ==12285== Using valgrind-3.1.1, a dynamic binary instrumentation framework. ==12285== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al. ==12285== For more details, rerun with: -v ==12285== ==12285== My PID = 12285, parent PID = 12284. Prog and args are: ==12285== ./myprojd ==12285== ==12285== Syscall param sigaltstack(ss) points to uninitialised byte(s) ==12285== at 0x3AD682EDA9: sigaltstack (in /lib64/tls/libc-2.3.4.so) ==12285== by 0x6488638: boost::detail::signal_handler::~signal_handler() (in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0) ==12285== by 0x648975E: boost::execution_monitor::catch_signals (boost::unit_test::callback0<int> const&) (in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0) ==12285== by 0x6489813: boost::execution_monitor::execute (boost::unit_test::callback0<int> const&) (in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0) ==12285== by 0x648F2E4: boost::unit_test::framework::run(unsigned long, bool) (in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0) ==12285== by 0x649BD02: boost::unit_test::unit_test_main(bool (*)(), int, char**) (in /<path_to>/libboost_unit_test_framework-gcc34-mt-1_36.so.1.36.0) ==12285== by 0x4147F0: main (init.cpp:132) ==12285== Address 0x7FEFFF3B0 is on thread 1 stack ==12285== ==12285== ERROR SUMMARY: 6 errors from 1 contexts (suppressed: 4 from 1) ==12285== malloc/free: in use at exit: 190,112 bytes in 1,869 blocks. ==12285== malloc/free: 23,128 allocs, 21,259 frees, 2,520,845 bytes allocated. ==12285== For counts of detected errors, rerun with: -v ==12285== searching for pointers to 1,869 not-freed blocks. ==12285== checked 2,184,272 bytes. ==12285== ==12285== LEAK SUMMARY: ==12285== definitely lost: 0 bytes in 0 blocks. ==12285== possibly lost: 0 bytes in 0 blocks. ==12285== still reachable: 190,112 bytes in 1,869 blocks. ==12285== suppressed: 0 bytes in 0 blocks. ==12285== Reachable blocks (those to which a pointer was found) are not shown. ==12285== To see them, rerun with:
Of course, I ran this in debug mode (although, as I said, the error only occurs in release mode). If I run valgrind in release mode, I get the same result (maybe less details like the #s line). This shows that the problem is somehow in boost-1.36, or, perhaps, in my definition of init_unit_test_suite? It is clear that I can try to run using boost-1.39 on all platforms; but unfortunately, we are currently on boost-1.36 for RHEL4 and VS2005, and therefore this may not be entirely practical.
I also notice that forcing some log output to the console at the point where the test fails allows you to pass the test (not good, I know)! Suspecting that this may be due to the fact that I commented on the entire output of the log and ran the command valgrind - so that posted above. If you need code snippets of the init_unit_test_suite function; I can post this if that helps. Any ideas to solve this problem are welcome and much appreciated.
05/26/2011 Edit:
Here's init_unit_test_suite - rate it if anyone can take a look.
std::ofstream log_stream; std::ofstream report_stream; const_string retrieve_framework_parameter( const_string cla_name, int argc, char** argv ) { //- first try to find parameter among command line arguments if present if( argc ) { //- locate corresponding cla name if( !cla_name.is_empty() ) { for( int i = 1; i < argc; ++i ) { if( cla_name == const_string( argv[i], cla_name.size() ) && argv[i][cla_name.size()] == '=' ) { const_string result = argv[i] + cla_name.size() + 1; for( int j = i; j < argc; ++j ) { argv[j] = argv[j+1]; } --argc; return result; } } } } return std::getenv( cla_name.begin() ); } //! Format results to CPP UNIT xml class simple_report_formatter : public results_reporter::format { public: virtual void results_report_start( std::ostream&) { } virtual void results_report_finish( std::ostream&) { } virtual void test_unit_report_start(test_unit const&, std::ostream&) { } virtual void test_unit_report_finish(test_unit const& tu, std::ostream& out) { if( tu.p_type == tut_case ) { const test_results& r = results_collector.results(tu.p_id); if( r.passed() ) { out<<"[PASS] "; } else { out<<"[FAIL] "; } out<<"Test Case <unit_"<<tu.p_name.get()<<"> "; if( !r.passed() ) { out<<" - "; out<<"!! Assertions failed: "<<r.p_assertions_failed; out<<" - See log files for details on failures !!"; } out<<std::endl;