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

_______________________________________________
macports-dev mailing list
macports-dev@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macports-dev

Reply via email to