#2889 closed Bugs (fixed)
Unit Test framework does things that OS X's malloc dislikes
Reported by: | Owned by: | Gennadiy Rozental | |
---|---|---|---|
Milestone: | Boost 1.41.0 | Component: | test |
Version: | Boost Release Branch | Severity: | Showstopper |
Keywords: | osx | Cc: | akos@… |
Description
Using the attached file, compiled as follows, OS X's malloc reports an invalid free. This is annoying, as we run our test with such instrumentation to catch other kinds of errors.
This is Mac OS X 10.5.6. Boost 1.38 installed by MacPorts.
$ g++ -Wall tests/libport/cli.cc -o cli -I/opt/local/include -L/opt/local/lib -lboost_unit_test_framework-mt $ MallocErrorAbort=1 MallocScribble=1 ./cli cli(50514) malloc: enabling abort() on bad malloc or free cli(50514) malloc: enabling scribbling to detect mods to free blocks cli(50514) malloc: enabling abort() on bad malloc or free Running 1 test case... *** No errors detected cli(50514) malloc: *** error for object 0x55555555: Non-aligned pointer being freed *** set a breakpoint in malloc_error_break to debug zsh: abort MallocErrorAbort=1 MallocScribble=1 ./cli $ g++ --version i686-apple-darwin9-g++-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5484) Copyright (C) 2005 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.
The documentation for MallocScribble (man malloc) reads:
If set, fill memory that has been deallocated with 0x55 bytes. This increases the likelihood that a program will fail due to accessing memory that is no longer allocated.
Attachments (1)
Change History (10)
by , 14 years ago
comment:1 by , 13 years ago
Investigation results: The stack trace for the error is:
Breakpoint 1, 0x94ddf4a9 in malloc_error_break () (gdb) bt #0 0x94ddf4a9 in malloc_error_break () #1 0x94dda497 in szone_error () #2 0x94d04463 in szone_free () #3 0x94d042cd in free () #4 0x0002ee92 in boost::unit_test::framework_impl::clear () #5 0x0002efbd in boost::unit_test::framework_impl::~framework_impl () #6 0x00008453 in __tcf_1 () #7 0x94d26cfc in __cxa_finalize () #8 0x94d26bf0 in exit () #9 0x000025c7 in start ()
comment:2 by , 13 years ago
Same behavior experienced with Boost.Filesystem trying to run "simple_ls.cpp" (from Boost.Filesystem tutorials).
Using:
- Mac OS X 10.5.6
- g++ 4.3.3
- Boost 1.38
Here is the stack trace:
Breakpoint 1, 0x94f824a9 in malloc_error_break () (gdb) bt #0 0x94f824a9 in malloc_error_break () #1 0x94f7d497 in szone_error () #2 0x94ea7463 in szone_free () #3 0x94ea72cd in free () #4 0x001b6745 in operator delete () #5 0x9281f02a in std::string::_Rep::_M_destroy () #6 0x9281f99d in std::string::_M_mutate () #7 0x9281fa44 in std::string::_M_replace_safe () #8 0x9281fae8 in std::string::assign () #9 0x00015bed in boost::filesystem::detail::get_current_path_api () #10 0x00004dee in boost::filesystem::current_path<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> > () #11 0x0000507b in boost::filesystem::initial_path<boost::filesystem::basic_path<std::string, boost::filesystem::path_traits> > () #12 0x00001a4b in main ()
Please note that the bug seems to be specific to Mac OS X.
comment:3 by , 13 years ago
Severity: | Problem → Regression |
---|
It is worth noting that Valgrind has the same opinion: something invalid is done. This is Mac OS X 10.5, boost 1.39:
==71960== Memcheck, a memory error detector ==71960== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==71960== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info ==71960== Command: ./cli ==71960== --71960-- ./cli: --71960-- dSYM directory is missing; consider using --dsymutil=yes Running 1 test case... *** No errors detected ==71960== Invalid read of size 4 ==71960== at 0x7969F: __tcf_1 (in /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x21FDBB: __cxa_finalize (in /usr/lib/libSystem.B.dylib) ==71960== by 0x21FCAF: exit (in /usr/lib/libSystem.B.dylib) ==71960== by 0x198A: (below main) (in ./cli) ==71960== Address 0x40d684 is 20 bytes inside a block of size 24 free'd ==71960== at 0x13B1A: operator delete(void*) (vg_replace_malloc.c:346) ==71960== by 0x7D65E: 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 /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x7D70E: 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 /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x7A0E3: boost::unit_test::framework::deregister_test_unit(boost::unit_test::test_unit*) (in /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x95219: boost::unit_test::test_unit::~test_unit() (in /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x7969B: __tcf_1 (in /opt/local/lib/libboost_unit_test_framework-mt.dylib) ==71960== by 0x21FDBB: __cxa_finalize (in /usr/lib/libSystem.B.dylib) ==71960== by 0x21FCAF: exit (in /usr/lib/libSystem.B.dylib) ==71960== by 0x198A: (below main) (in ./cli) ==71960== ==71960== ==71960== HEAP SUMMARY: ==71960== in use at exit: 4,484 bytes in 11 blocks ==71960== total heap usage: 61 allocs, 50 frees, 531,099 bytes allocated ==71960== ==71960== LEAK SUMMARY: ==71960== definitely lost: 0 bytes in 0 blocks ==71960== indirectly lost: 0 bytes in 0 blocks ==71960== possibly lost: 0 bytes in 0 blocks ==71960== still reachable: 4,104 bytes in 2 blocks ==71960== suppressed: 380 bytes in 9 blocks ==71960== Rerun with --leak-check=full to see details of leaked memory ==71960== ==71960== For counts of detected and suppressed errors, rerun with: -v ==71960== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
The problem is now even more acute on Snow Leopard (10.6), with Boost.Test 1.40. Using the same file, and compiled with Apple's GCC-4.2:
$ ./cli Running 1 test case... *** No errors detected cli(38688) malloc: *** error for object 0x30001002034f0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug zsh: abort ./cli
i.e., the test fails. My whole test suite is red, not a single test passes, because of this problem. If you are still hoping this is some compiler error, I'm afraid to say that GCC 4.5 features the exact same behavior.
The stack trace is beautifully useless. "Of course" it is some destructor that is doing something wrong. But which one is an exercise left to the reader.
#0 0x00007fff8605dbe1 in malloc_error_break () #1 0x00007fff85f87203 in free () #2 0x0000000100010d62 in __tcf_1 () #3 0x00007fff85f933f4 in __cxa_finalize () #4 0x00007fff85f9330c in exit () #5 0x0000000100001487 in start ()
Changing to regression, as it's getting worse.
comment:4 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:5 by , 13 years ago
Milestone: | Boost 1.39.0 → Boost 1.41.0 |
---|---|
Resolution: | fixed |
Severity: | Regression → Showstopper |
Status: | closed → reopened |
Version: | Boost 1.38.0 → Boost Release Branch |
The following crashes on Mac 10.6. ie completely broken 10.6 v1.40 and trunk
rotor:~ tegtmeye$ g++ boost_test.cc /usr/local/lib/libboost_unit_test_framework.a rotor:~ tegtmeye$ ./a.out Running 4 test cases...
* No errors detected a.out(69716) malloc: * error for object 0x30001002002e0: pointer being freed was not allocated * set a breakpoint in malloc_error_break to debug Abort trap rotor:~ tegtmeye$ cat boost_test.cc #define BOOST_TEST_MODULE footest test #include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( test1 ) {
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_CASE( test2 ) {
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_CASE( test3 ) {
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_CASE( test4 ) {
BOOST_CHECK( true );
} rotor:~ tegtmeye$ g++ --version i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) Copyright (C) 2007 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.
rotor:~ tegtmeye$
comment:6 by , 13 years ago
Cc: | added |
---|
comment:8 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:9 by , 13 years ago
It seems this was merged into the release branch after the 1.41.0 branch. I hope the fix will be included in the next release. BTW this affects FreeBSD in the very same way.
A source file to reproduce the problem