Opened 13 years ago
Closed 13 years ago
#3432 closed Bugs (fixed)
Boost:Test pointer error with g++ 64-bit on Mac OS X 10.6 Snow Leopard
Reported by: | Owned by: | Gennadiy Rozental | |
---|---|---|---|
Milestone: | Component: | test | |
Version: | Boost 1.40.0 | Severity: | Problem |
Keywords: | test mac "snow leopard" pointer 64-bit | Cc: |
Description
When I compile a program which uses Boost:Test on Mac OS X 10.6 "Snow Leopard" for 64-bit architecture, I get an error when the program is run. To demonstrate this error, I creating a sample program (see attached file), which contains 10 test suites, each containing 10 test cases. The error only appears after a certain number of test suites/cases have been added to the program, because I could not reproduce the error with 10 test suites with 1 test case each. The compile commands and out put are:
$ g++ -g -c -fmessage-length=0 -o"src/UnitTest.o" "../src/UnitTest.cpp" $ g++ -o "UnitTest" ./src/UnitTest.o $ ./UnitTest Running 100 test cases... *** No errors detected UnitTest(73438) malloc: *** error for object 0x3000100600630: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap
I then tried compiling this with g++ 4.0.1 (apple), g++ 4.2.1 (apple), g++ 4.4.1, and icpc 11.1 with and without -m32 option; all on Mac OS X 10.6. In addition, I also compiled my test program with g++ 4.3.3 on Ubuntu Linux 9.04 (x86_64 version) with and without -m32 option. Here are the results of those tests.
g++ Mac OS X 10.6: v 4.0.1 32bit: Pass v 4.0.1 64bit: Fail v 4.2.1 32bit: Pass v 4.2.1 64bit: Fail v 4.4.1 32bit: Pass v 4.4.1 64bit: Fail
icpc Mac OS X 10.6: v 11.1 32bit: Pass v 11.1 64bit: Pass
g++ Linux x86_64: v 4.3.3 64bit: Pass
It appears that the error only occurs with g++ 64bit code on Mac OS X.
While debugging the program I found that the error occurs in boost/test/impl/framework.ipp in void boost::unit_test::framework_imp::clean(), when delete is called. However, I do not think the error is in this function. Since the problem is not present when it is compiled as a 32-bit program, it is likely caused by a 64-bit value being written to a 32-bit address or something like that.
Attachments (3)
Change History (8)
by , 13 years ago
Attachment: | UnitTest.cpp added |
---|
comment:1 by , 13 years ago
comment:2 by , 13 years ago
If I remember correctly, Mac OS X is a derivative of FreeBSD. I do not know how much they have in common today, but it is possible that it is a bug which still exists in the two OS's.
comment:3 by , 13 years ago
For me it fails in the attached example with a single case on FreeBSD. On OS X I need more test cases to show the problem.
The point of failure is the same on both platforms.
On OS X and FreeBSD background: Possible, but also possibly not. I'd prefer not to jump to conclusions.
comment:4 by , 13 years ago
Please see the attached patch. This resolves the problem for me on OS X and FreeBSD.
On OS X the single test case example can be made to fail by setting the "MallocScribble" environment variable.
The problem is that the delete in framework_impl::clear() happens through a reference to the actual pointer in the m_test_units container, and the destructor of the object removes itself from the container. Once the object is removed from the container (in the the destructor) the reference is no longer valid, and the underlying call to free() uses the now-invalid reference.
Solution: Keep a copy of the pointer to be deleted on the stack.
I see this problem on Mac OSX 10.6.1 as in the original report, and also on FreeBSD 7.2-STABLE, 64 bit version. I do not see the problem on 32 bit Windows XP with Visual C++ 2005 Express.