Re: boost test_unit problem when using gcc 4.0.1
Re: boost test_unit problem when using gcc 4.0.1
- Subject: Re: boost test_unit problem when using gcc 4.0.1
- From: Ananda Tallur <email@hidden>
- Date: Fri, 24 Mar 2006 18:38:50 +0100
Hello,
I have further investigated on this issue, by analysing what happens
in the unit_test_framework.
I could come out with a simple test program, only using shared
pointer, which fails on Mac OS X, when compiled with gcc 4.0.1
(coming with latest XCode 2.2.1), or gcc 4.1 from darwinports, when
optimization is enabled (-O, -O1, or -O2).
I am using boost 1.33.1, but is it the same with 1.33.0 and 1.32.0.
Below the new test program :
--- macosx_gcc4problem.cpp ---
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
using namespace boost;
struct A {
int value;
~A ()
{
std::cout << "SampleTest destructor" << std::endl << std::flush;
}
};
struct B
{
B (shared_ptr <A> val)
: a (val) {}
shared_ptr <A> a;
};
struct C {
C (B val)
: b (val) {}
B b;
};
struct D
{
D (C val)
: c (val)
{}
C c;
};
D create ()
{
boost::shared_ptr <A> a (new A);
a->value = 12345;
return D (C (B (a)));
}
int main (int argc, char * argv [])
{
D d = create ();
std::cout << "value = " << d.c.b.a->value << std::endl <<
std::flush;
return 0;
}
--- macosx_gcc4problem.cpp ---
To compile it :
g++-4.0 -O2 -I <path-to-boost-includes> macosx_gcc4problem.cpp -o
macosx_gcc4problem
Output :
When run, the value displayed is 13691, instead of 12345.
Analysis :
-> there is a problem in shared_ptr reference counting, in line :
return D (C (B (a)));
Just after D creation, the reference counter is a 1, instead of
2 as it should.
And when leaving create () function, the automatic variable a is
detroyed, which changes the reference counter to 0 and detroys the A
object.
In main function after call to create, the reference counter
should be of 1, and the object A should be available on the heap.
But it has already been destroyed, leading to an incorrect
result being displayed.
In worst cases, a segmentation fault may happen.
Remark : if changing the constructor of B, so that a const reference
to the shared_ptr is passed, instead of the shared_ptr itself, it
works :
---
struct B
{
B (const shared_ptr <A> &val)
: a (val) {}
---
To further investigate the problem, it may be needed to analyse the
assembly code generated by the gcc 4 compiler.
The problem is clearly in the line : return D (C (B (a)));
There may be a problem with management of temporary variables,
combined with optimisations.
I require the help of other developpers, because I think this problem
could concern many of us, and not only boost users.
Thanks
Anand
On 22 févr. 06, at 17:32, Ananda Tallur wrote:
Hello,
I would like to submit a problem we recently discovered, when using :
* gcc 4.0.1 : Apple version coming with XCode 2.2.1 (build 5250) or
gcc 4.0.2 delivered by darwinports.
* boost library, tried with 1.33.1, 1.33.0
* using optimization level, either -O, -O1 or -O2
The problem does not occur when :
* using Apple gcc 3.3, both with or without optimization
* not using optimization (-O0)
Below is the sample program :
---- file boost_unit_test_gcc4_pb_sample.cpp ---
#include <iostream>
#include <boost/test/unit_test.hpp>
using boost::unit_test_framework::test_suite;
using boost::unit_test_framework::test_case;
using namespace std;
class SampleTest {
public:
SampleTest (int val) :
a (val)
{
}
int a;
void sampleTest ()
{
std::cout << "a : " << a << std::endl;
BOOST_CHECK_EQUAL (a, 12345);
}
};
test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
test_suite* test= BOOST_TEST_SUITE( "Sample test" );
boost::shared_ptr<SampleTest> instance (new SampleTest (12345));
test->add (BOOST_CLASS_TEST_CASE ( & SampleTest::sampleTest,
instance));
return test;
}
---- end-of-file boost_unit_test_gcc4_pb_sample.cpp ---
And the command used for compiling :
BOOST_PATH=<path-to-your-boost-install>
/usr/bin/g++-4.0 -O2 -I${BOOST_PATH}/include -L${BOOST_PATH}/lib -
lboost_unit_test_framework boost_unit_test_gcc4_pb_sample.cpp -o
boost_unit_test_gcc4_pb_sample
When compiled when the above command, and running the program :
export DYLD_LIBRARY_PATH=${BOOST_PATH}/lib
./boost_unit_test_gcc4_pb_sample
The result is the following :
----
Running 1 test case...a : 13691
boost_unit_test_gcc4_pb_sample.cpp(18): error in "
SampleTest::sampleTest": check a == 12345 failed [13691 != 12345]
*** 1 failure detected in test suite "Sample test"
---
When compiled without optimization (-O0), and running, the result is :
----
Running 1 test case...a : 12345
*** No errors detected
----
It seems that when sampleTest () method is called by unit_test
framework, adress of "a" variable is wrong, leading to a test failure.
When, instead of using a class or struct attribute for variable
"a", either a global, or class static variable is used, the problem
disappears.
Has anyone some experience using Boost unit_test framework on Mac
OS X, using gcc 4 ?
Any help would be greatly appreciated !
Regards,
Anand
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden