C++:所有增强路径操作段错误(OSX/GCC)

Ami*_*iri 7 c++ macos gcc boost boost-filesystem

我正在尝试使用增强路径执行几乎任何操作,从而获得一致的段错误.

(编辑:似乎所有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;
}
Run Code Online (Sandbox Code Playgroud)

以上只是一个例子,以下也是段错:
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
Run Code Online (Sandbox Code Playgroud)

通过Homebrew安装GCC和Boost .

系统规格:

OSX:   10.9.4
GCC:   4.9.1
Boost: 1.0.55_2
Run Code Online (Sandbox Code Playgroud)

编辑:

-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
Run Code Online (Sandbox Code Playgroud)

Segfault信号处理程序(摘自此问题):

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);
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*esh 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
Run Code Online (Sandbox Code Playgroud)

然后内置它(仅静态;有一个构建问题,它无法在OSX下的这种情况下制作动态库 - ld抱怨该-h选项不受支持):

$ ./b2 --layout=tagged threading=multi link=static toolset=gcc-4.8
Run Code Online (Sandbox Code Playgroud)

当我编译你的代码时(由于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

$
Run Code Online (Sandbox Code Playgroud)

即在这种情况下它运作得很好.

这是什么意思?

  • OSX上的C++库是一个完整的PITA,如果你想尝试混合g++clang++
  • 因为所有clang++代码默认都是构建的,如果你打算用它们构建它们,libc++你将不得不拥有任何c++库的私有副本g++
  • homebrew只是在编译时遵循命令 clang++

这是一团糟,但如果你坚持<sarcasm> 一个真正的编译器 </ sarcasm>,那么你会没事的.TBH我更喜欢clang的错误信息,静态分析非常好; 但是如果你必须使用g++,你必须保留c++你想要使用的任何库的私有副本,也要编译g++.