Mac OS X和静态boost库 -> std :: string失败

6
我在使用静态boost库时遇到了一些非常奇怪的问题(来自MacPorts的Boost 1.45.0-2,编译为fat/universal(x86/x86_64)库),在Mac OS X 10.6.6下使用GCC 4.5。
错误消息为:
main(78485) malloc: *** error for object 0x1000e0b20: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
[1]    78485 abort (core dumped)

以下是一个微小的示例代码,将会触发此问题:

#define BOOST_FILESYSTEM_VERSION 3
#include <boost/filesystem.hpp>
#include <iostream>

int main (int argc, char **argv) {
  std::cout << boost::filesystem::current_path ().string () << '\n';
}

这个问题通常在将静态boost库链接到二进制文件时出现。尽管动态链接可以正常工作。
更多信息:
测试/使用的gcc版本:Apple GCC 4.2.1(可用/运行),MacPorts GCC 4.5.2(失败)
测试/使用的标志:无,-fPIC,-fPIC -g,-fPIC -g -ggdb3 -gdwarf-2 -O0
使用MP GCC 4.5.2 / 上述任何标志的gdb输出:
(gdb) run
Starting program: /Users/ionic/crashtest/bin/ctest  Reading symbols for shared libraries .++++++++++++++++++++++.................................................................................................................. done
ctest(80366) malloc: *** error for object 0x100fe6b20: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug

Program received signal SIGABRT, Aborted. 0x00007fff81a4e616 in __kill ()
(gdb) bt full
#0  0x00007fff81a4e616 in __kill () No symbol table info available.
#1  0x00007fff81aeecca in abort () No symbol table info available.
#2  0x00007fff81a066f5 in free () No symbol table info available.
#3  0x0000000100f763e9 in std::string::_M_mutate () No symbol table info available.
#4  0x0000000100f7644c in std::string::_M_replace_safe () No symbol table info available.
#5  0x0000000100f77edd in std::string::replace () No symbol table info available.
#6  0x000000010000713d in std::string::_M_rep () at /usr/include/c++/4.2.1/bits/basic_string.h:1412
        to = (string &) Cannot access memory at address 0x0

看起来使用苹果(相当老的)GCC版本运行良好,但是使用MacPorts构建的新GCC版本则出现了严重问题。

otool -L ctest:

./../../bin/ctest:
        /opt/local/lib/gcc45/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.14.0)
        /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 625.0.0)
        /opt/local/lib/gcc45/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)

我曾经看到过很多关于OS X的报告,涉及GCC 4.2和_GLIBCXX_DEBUG宏设置的类似bug,但是这个问题似乎更普遍,因为我既没有使用XCode,也没有设置宏(即使取消定义也没用。我只是想确保它与此问题确实没有关系。)这似乎与这个问题完全无关,因为相同的代码在Apple的GCC上运行良好。

由于Apple的GCC尚未包含任何C++0x功能,因此我确实希望使用当前稳定的GCC版本。

是否有人知道为什么会发生这种情况,甚至可能有解决方案(而不是使用动态库解决方法)?

最好的问候,

Mihai


我已经对帖子进行了相当大的更新,并添加了全新的重要信息。 :) - Ionic
使用哪个版本的GCC和libstdc++编译了Boost?如果是由Apple提供的,我敢打赌它与MacPorts中的GCC不兼容。 - leedm777
没错。我很久以前就已经想到了这个(实际上是在我的最后一条评论后的第二天)。会添加一些答案。 - Ionic
1个回答

7
问题在于Boost是使用苹果的GCC 4.2.1构建的,而我正在使用不同的编译器构建项目。
当我尝试链接静态Boost库时,也将GCC 4.2.1的libstdc++放入了二进制文件中。 然而,同时另一个GCC版本也在链接其libstdc++,因此存在命名空间问题,因此错误的函数被调用等问题。
最简单的解决方法是使用目标GCC版本重新构建Boost,并重试构建程序(当然要使用自己构建的Boost)。
请注意:不要尝试更改MacPorts用于构建Boost的编译器(甚至不容易实现),否则可能会导致系统破坏。相反,自己构建Boost。

你可以看到otool显示它正在使用/opt中的libstdc++,而不是系统范围内的库。 - ismail
大家好。我正在尝试在Mac OS 10.6.6桌面上运行最新稳定版本的gcc 4.5.2。关于为最新的Mac OS X版本构建gcc的信息很少(gcc页面列出了10.5的成功案例)。是使用MacPorts的方式吗?谢谢! - Scott Davies
是的,只需使用MacPorts编译和安装更新的GCC版本即可。它们将缺少所有Apple扩展,但在其他方面工作正常。 - Ionic
相同的症状和解决方案,稍有不同的问题,但同样适用:在重建项目时,我错过了重新编译一个依赖项的新版本GCC(4.5-> 4.6)。由于ABI差异,您会遇到最奇怪的错误。重新编译很容易,但是挖掘ASM以查找boost中可能存在的错误却很麻烦。简单的解决方案胜利! - Sean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接