Opened 13 years ago
Closed 13 years ago
#3635 closed Bugs (duplicate)
basic unit test sample memory issues
Reported by: | Owned by: | Gennadiy Rozental | |
---|---|---|---|
Milestone: | Boost 1.41.0 | Component: | test |
Version: | Boost 1.40.0 | Severity: | Problem |
Keywords: | Cc: | akos@… |
Description
it seems that the basic unit test sample in the unit test framework documentation has some memory issues. the sample is example01 from page http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/utf/user-guide/test-organization/manual-nullary-test-case.html , and it seems to make an invalid read according to valgrind, and leak according to google perftools.
output of valgrind:
$ cat example01.cpp #include <boost/test/included/unit_test.hpp> using namespace boost::unit_test; //____________________________________________________________________________// void free_test_function() { BOOST_CHECK( true /* test assertion */ ); } //____________________________________________________________________________// test_suite* init_unit_test_suite( int argc, char* argv[] ) { framework::master_test_suite(). add( BOOST_TEST_CASE( &free_test_function ) ); return 0; } //____________________________________________________________________________// $ g++ -o example01 example01.cpp $ $ valgrind ./example01 ==16385== Memcheck, a memory error detector. ==16385== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==16385== Using LibVEX rev 1854, a library for dynamic binary translation. ==16385== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==16385== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework. ==16385== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==16385== For more details, rerun with: -v ==16385== Running 1 test case... *** No errors detected ==16385== Invalid read of size 8 ==16385== at 0x472F35: boost::unit_test::framework_impl::clear() (in /home/maroy/tmp/tests/example01) ==16385== by 0x47308E: boost::unit_test::framework_impl::~framework_impl() (in /home/maroy/tmp/tests/example01) ==16385== by 0x560B6AC: exit (in /lib/libc-2.8.90.so) ==16385== by 0x55F346C: (below main) (in /lib/libc-2.8.90.so) ==16385== Address 0x59516d8 is 40 bytes inside a block of size 48 free'd ==16385== at 0x4C24DAD: operator delete(void*) (vg_replace_malloc.c:342) ==16385== by 0x44EBA4: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned long const, boost::unit_test::test_unit*> > >::deallocate(std::_Rb_tree_node<std::pair<unsigned long const, boost::unit_test::test_unit*> >*, unsigned long) (in /home/maroy/tmp/tests/example01) ==16385== by 0x44EBCC: 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*> > >::_M_put_node(std::_Rb_tree_node<std::pair<unsigned long const, boost::unit_test::test_unit*> >*) (in /home/maroy/tmp/tests/example01) ==16385== by 0x44EC17: 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*> > >::_M_destroy_node(std::_Rb_tree_node<std::pair<unsigned long const, boost::unit_test::test_unit*> >*) (in /home/maroy/tmp/tests/example01) ==16385== by 0x44EC60: 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*> > >::_M_erase(std::_Rb_tree_node<std::pair<unsigned long const, boost::unit_test::test_unit*> >*) (in /home/maroy/tmp/tests/example01) ==16385== by 0x44EC93: 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*> > >::clear() (in /home/maroy/tmp/tests/example01) ==16385== by 0x472A3E: 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(std::_Rb_tree_iterator<std::pair<unsigned long const, boost::unit_test::test_unit*> >, std::_Rb_tree_iterator<std::pair<unsigned long const, boost::unit_test::test_unit*> >) (in /home/maroy/tmp/tests/example01) ==16385== by 0x472AC0: 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/maroy/tmp/tests/example01) ==16385== by 0x472AF2: std::map<unsigned long, 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/maroy/tmp/tests/example01) ==16385== by 0x42950D: boost::unit_test::framework::deregister_test_unit(boost::unit_test::test_unit*) (in /home/maroy/tmp/tests/example01) ==16385== by 0x4295D5: boost::unit_test::test_unit::~test_unit() (in /home/maroy/tmp/tests/example01) ==16385== by 0x472E21: boost::unit_test::test_case::~test_case() (in /home/maroy/tmp/tests/example01) ==16385== ==16385== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 8 from 1) ==16385== malloc/free: in use at exit: 0 bytes in 0 blocks. ==16385== malloc/free: 373 allocs, 373 frees, 51,963 bytes allocated. ==16385== For counts of detected errors, rerun with: -v ==16385== All heap blocks were freed -- no leaks are possible.
output of google perf tools:
$ g++ -ltcmalloc -lpthread -o example01 example01.cpp $ env HEAPCHECK=normal ./example01HeapProfiler: Removing old profile /tmp/example01.15966._main_-beg.heap HeapProfiler: Removing old profile /tmp/example01.15966._main_-end.heap HeapChecker: Starting check "_main_" HeapChecker: Ignoring 10 reachable objects of 415 bytes Running 1 test case... *** No errors detected HeapChecker: Checking for whole-program memory leaks HeapChecker: Ending check "_main_" HeapChecker: Ignoring 23 reachable objects of 1358 bytes HeapChecker: Heap memory leaks of 57 bytes and/or 1 allocations detected by check "_main_". HeapChecker: To investigate leaks manually use e.g. cd /home/maroy/tmp/tests; /usr/bin/pprof ./example01 "/tmp/example01.16547._main_-end.heap" --inuse_objects --lines --edgefraction=1e-10 --nodefraction=1e-10 --gv 2>/dev/null HeapChecker: Below is this pprof's output: 1 100.0% 100.0% 1 100.0% 0x00007f156bca4011 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156bca57a3 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156c1400a6 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156bca5541 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156c1403d6 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156c141963 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156c143136 ??:0 0 0.0% 100.0% 1 100.0% 0x00007f156bca48bb ??:0 HeapChecker: crashing because of leaks Segmentation fault
this is on an ubuntu 8.10 64 bit using g++ 4.3.2:
$ uname -a Linux tomodachi 2.6.27-15-generic #1 SMP Tue Oct 20 06:50:36 UTC 2009 x86_64 GNU/Linux $ g++ --version g++ (Ubuntu 4.3.2-1ubuntu12) 4.3.2 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Note:
See TracTickets
for help on using tickets.
Duplicates #2889