help with g++-mp-4.5

Titus von Boxberg titus at v9g.de
Thu Jun 9 01:47:32 PDT 2011


Am 07.06.2011 um 11:41 schrieb Ryan Schmidt:

> On Jun 7, 2011, at 01:16, Titus von Boxberg wrote:
> 
>> The same problem is given here:
>> http://stackoverflow.com/questions/4697859/mac-os-x-and-static-boost-libs-stdstring-fail
>> 
>> But I currently do not understand the problem.
>> And the "solution" given there as far as I get it would mean that
>> macport's c++ libraries are useless in conjunction with mp-g++?
> 
> Reading that Stack Overflow post, it says that the reason their program compiled with gcc 4.5 doesn't work is that the boost library they're trying to statically link with was built with gcc 4.2. The solution was to either build their program with gcc 4.2 too, or to build boost with gcc 4.5 too. It's best to compile all parts of your project with the same compiler to avoid these types of problems. The article says the problem may also only appear when linking to static libraries, so link to the dynamic library instead. On Mac OS X, dynamic linking is preferred to static linking anyway; possibly this problem is one of the reasons for that recommendation.
> 
> In your case, you're trying to link with cppunit, not boost, but other than that it seems similar. Except that the compile command you've shown doesn't seem to be specifically requesting to link with the static library. I thought dynamic linking was the default when both are available (which they are for cppunit). Maybe you need to explicitly request the dynamic library.
> 
> MacPorts does not provide users with a means of specifying what compiler they want to use; instead it's up to the port maintainers to choose the correct compiler or provide compiler options. And unless there is a good reason why it won't work, most ports will use the default compiler, which on Snow Leopard is Apple's build of gcc 4.2. Assuming you require gcc 4.5 and 4.2 is not sufficient, you could try to override it when installing cppunit (sudo port install cppunit configure.cc=macports-gcc-4.5) but I don't know whether this will work on cppunit, and it's certainly not something we will support. You could also build cppunit manually with gcc 4.5. 
> 
Just in case someone is interested:

the pointer being freed that was not allocated is
__ZNSs4_Rep20_S_empty_rep_storageE 
or better demangled
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_empty_rep_storage

This is a constant variable allocated in the data segment 
of libstdc++.dylib denoting an empty string (representation).

The problem occurs when the constructor of std::string is called from
a piece of code that uses a different libstd++.dylib than the code which
calls the destructor.
In this case, the constructor of std::string is called from CppUnit::Message::Message()
for it's member variable of type string, the string::string() being in
libcppunit.dylib, using /usr/lib/libstdc++.dylib.
string::~string() is called from the main program, having inlined
the destruction of Message, and using macport-gcc45's /opt/local/lib/gcc45/libstdc++.dylib.

Presumably (I did not fully trace through ~string), the string's _Rep class
in the mp-gcc45's libstdc++ compares it's address to the address of it's
own "empty string" constant which is not equal to the address of
/usr/lib/libstdc++.dylib's constant that gets used during allocation.
Thus, the check that prevents deallocation of this static constant fails.

With the trivial test program, there are several ways around this crash.
- one could implement ~Message in cppunit's Message.cpp. Then the destructor
  of Message references the same libstdc++ for ~string() that the constructor
  references for string().
- use install_name_tool to change the libstd++.dylib referenced by the
  main program to be the same that gets referenced by libcppunit.dylib
- install_name_tool the other way round.

I think that none of these are viable for "real software".

Best would be if the "empty string" constant in mp-gcc45's libstdc++.dylib
would be kindof weak symbol that get's kicked out by dyld when also loading
/usr/lib/libstdc++.dylib.
Don't know yet if that's possible.
And, presumably, also this would only work if taking out (which I did)
--enable-fully-dynamic-string (which is deleting use of the "empty string" constant)
of mp-gcc's Portfile configure parameters, since this is not used for apple's libstdc++.

So this was the hard way to find out that Ryan is right ;-)

Regards
Titus



More information about the macports-dev mailing list