C ++: all segfault acceleration operations (OSX / GCC)

I get consistent segfaults with almost any operation that I try to perform using the accelerated path.

( Edit: It appears that all segfaulting functions are related to 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; } 

The above is just an example, followed also by segfault:
auto p = current_path(err);

BUT:
auto p = initial_path(err);

Compiled with:
g++-4.9 -lboost_filesystem -lboost_system -std=c++11 main.cpp -o ./path-test

Output:

 hello/../world Segmentation fault: 11 

Both GCC and Boost are installed via Homebrew .

System Specifications:

 OSX: 10.9.4 GCC: 4.9.1 Boost: 1.0.55_2 

Edit:

Compiled with -g and set the signal handler according to the comment, output:

 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 signal handler (derived from 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); } 
+7
c ++ gcc boost macos boost-filesystem
source share
2 answers

You mix implementations of the standard C ++ library.

Boost, when installed through brew, will be compiled using clang++ . This toolchain uses libc++ by default.

g++ insists on using its own implementation of libstdc++ .

These implementations are not compatible with binary data in which problems arise.

I extracted a new copy of boost in a subdirectory, did:

 $ ./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 

Then it is built (only static, there is a problem with the assembly where it is impossible to make dynamic libraries in this situation under OSX-ld complains that the -h option is not supported):

 $ ./b2 --layout=tagged threading=multi link=static toolset=gcc-4.8 

When I compiled your code (due to threading = multi, I had to add -mt to the link options):

 $ 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 $ 

i.e. in this case, it worked perfectly.

What does it mean?

  • C ++ libraries on OSX is full PITA if you are trying to mix g++ and clang++
  • because libc++ is created for all clang++ code by default, you will have to have private copies of any c++ if you intend to create them using g++
  • homebrew just executes orders when compiled with clang++

This is a mess, but if you stick with <sarcasm> one real compiler </sarcasm>, you'll be fine. TBH I prefer clang error messages, and static analysis is excellent; but if you need to use g++ , you will have to keep personal copies of any c++ that you want to use, also compiled with g++ .

+8
source share

In addition to Petesh's excellent answer, for those struggling with capacity building using gcc via homebrew:

 brew install boost --build-from-source --env=superenv --cc=gcc-<Your GCC version> 

Check out the --env=superenv , which is a recent addition to Homebrew, so make sure your brew is updated!

If you run into problems and are not sure if boost was compiled with gcc or clang, use otool -L in any dynamic boost library ( .dylib file) and find the libc++ or libstdc++ entry.

For example, by running the following command after I finally returned it correctly:

 otool -L /usr/local/lib/libboost_system.dylib 

It produces the following output:

 /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) 

The second entry shows that this is an increase in lib references to GCC libstd++ . If instead he said /usr/lib/libc++.dylib , then he is still linked to Apple clang runtime.

Please note that using brew allows you to use all the options (single / multi / static / dynamic), since the supporting formula includes patches to make sure that they compile successfully on OSX, which cannot be a base with increased vanilla.

+1
source share

All Articles