我正在尝试使用boost路径执行几乎所有操作的段错误。
(编辑:似乎所有的segfaulting函数都与current_path()
相关)
Sample program:
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <iostream>
using namespace std;
using namespace boost::filesystem;
using namespace boost::system;
int main(int argc, const char * argv[])
{
error_code err;
auto p = path("hello/../world");
cout << p.string() << endl;
path c = canonical(p, err);
cout << c.string() << endl;
}
以上只是一个例子,以下也是段错:
auto p = current_path(err);
和:
auto p = initial_path(err);
编译:
g++-4.9 -lboost_filesystem -lboost_system -std=c++11 main.cpp -o ./path-test
输出:
hello/../world
Segmentation fault: 11
通过 Homebrew 安装GCC和Boost。
系统规格:
OSX: 10.9.4
GCC: 4.9.1
Boost: 1.0.55_2
修改
使用-g
编译并根据注释安装了信号处理程序,输出:
hello/../world
Segfault:
0 path-test 0x000000010ea215b8 _Z7handleri + 28
1 libsystem_platform.dylib 0x00007fff8b9285aa _sigtramp + 26
2 ??? 0x00007fff67bdf1a1 0x0 + 140734933889441
3 path-test 0x000000010ea2196d _ZN5boost10filesystem9canonicalERKNS0_4pathERNS_6system10error_codeE + 69
4 path-test 0x000000010ea21518 main + 138
5 libdyld.dylib 0x00007fff832c35fd start + 1
6 ??? 0x0000000000000001 0x0 + 1
Segfault信号处理程序(取自this question):
void handler(int sig)
{
void *array[10];
size_t size;
size = backtrace(array, 10);
fprintf(stderr, "Segfault:\n");
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
答案 0 :(得分:8)
您正在混合C ++标准库的实现。
通过brew安装的Boost将使用clang++
进行编译。默认情况下,此工具链使用libc++
。
g++
坚持使用自己的libstdc++
实施。
这些实现不是二进制兼容的,这就是出现问题的地方。
我将一个新的boost副本提取到一个子目录中,做了一个:
$ ./bootstrap.sh --prefix=/usr/local/boost156 cxxflags="-arch i386 -arch x86_64" address-model=32_64 threading=multi macos-version=10.9 toolset=g++-4.8 stage
然后内置它(仅限静态;在OSX下无法在这种情况下制作动态库的构建问题 - ld抱怨不支持-h
选项):
$ ./b2 --layout=tagged threading=multi link=static toolset=gcc-4.8
当我编译你的代码时(由于threading = multi,我不得不在链接选项中添加-mt):
$ g++-4.8 -g -std=c++11 -Iboost_1_56_0 -Lboost_1_56_0/stage/lib -lboost_filesystem-mt -lboost_system-mt main.cpp -o ./path-test
$ ./path-test
hello/../world
$
即。在这种情况下它运作得很好。
这是什么意思?
g++
和clang++
clang++
代码默认使用libc++
构建,如果您打算使用{{1}构建它们,则必须拥有任何c++
库的私有副本} g++
这是一团糟,但如果你坚持使用&lt; sarcasm&gt; 一个真正的编译器&lt; / sarcasm&gt;,那么你会没事的。 TBH我更喜欢clang的错误信息,静态分析非常好;但如果必须使用clang++
,则必须保留要使用的任何g++
库的私有副本,并使用c++
进行编译。
答案 1 :(得分:1)
除了Petesh的优秀答案,对于任何通过自制软件使用gcc进行构建提升的人来说:
brew install boost --build-from-source --env=superenv --cc=gcc-<Your GCC version>
请注意--env=superenv
开关,这是Homebrew的新增内容,因此请确保您的brew是最新的!
如果您遇到问题并且不确定是否使用gcc或clang编译了boost,请在任何boost动态库(otool -L
文件)上使用.dylib
并查找{{ 1}}或libc++
条目。
例如,在我最终使其正常工作后运行以下命令:
libstdc++
产生以下输出:
otool -L /usr/local/lib/libboost_system.dylib
第二个条目显示此升级lib链接到GCC的/usr/local/lib/libboost_system.dylib:
/usr/local/lib/libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/local/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.20.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/usr/local/Cellar/gcc/4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
。如果相反它说libstd++
,那么它仍然与Apple的clang运行时相关联。
请注意,使用brew可以启用所有变体(单/多/静态/动态),因为公式的维护者包含补丁以确保它在OSX上成功编译 - 这可能不是带有香草增强的基础。