0

I'm trying to compile and run a C++11 program which uses Boost.Filesystem -- let's say to list the contents of a directory -- in a shared web hosting environment. Since the software installed on this system is generally 4 years old, and I need to use more recent versions of GCC and Boost to compile and run this program, I've gone ahead and compiled and locally installed GCC and Boost in my home directory.

My problem is that, although I am now able to compile and run C++11 programs which do not use the Boost.Filesystem library, anytime I try to run code which uses that library, a runtime error occurs. For one program I wrote, it was making an invalid free() on an address located in the heap. For another program (the one shown in this post), I get a segmentation fault.

What might be causing this issue, and how can I fix it?

I suspect that the problem lies somewhere in the fact that this system has pre-existing installations of GCC and Boost which may be duping the compiler.

I have GCC version 6.0.0 and Boost version 1.60.0 installed under ~/local/. So the g++ executable is at ~/local/bin/g++, the shared objects for the C++ runtime and Boost are under ~/local/lib64/ and ~/local/lib/, etc. When I compile or run my programs, I set LD_LIBRARY_PATH=$HOME/local/lib64:$HOME/local/lib so the locally installed shared objects are used (GCC requires three external libraries of its own to run). I have confirmed this with ldd.

Here is the test program which I am trying to get working:

#include <iostream>

#include <boost/filesystem.hpp>

using namespace std;
using namespace boost;

int main(int argc, char **argv) {

        if(argc != 2) {
                cerr << "Usage: " << argv[0] << " <directory>\n";
                return 1;
        }

        const char *dirname = argv[1];

        for(filesystem::directory_iterator i(dirname), n; i != n; ++i) {
                cout << *i << '\n';
        }

        return 0;
}

The result of compiling and running this program is:

% LD_LIBRARY_PATH=$HOME/local/lib64:$HOME/local/lib $HOME/local/bin/g++ -std=c++11 -Wall -B$HOME/local/bin -B$HOME/local/include -B$HOME/local/lib64 -B$HOME/local/lib -lboost_system -lboost_filesystem
% LD_LIBRARY_PATH=$HOME/local/lib64:$HOME/local/lib ./a.out .
Segmentation fault

Backtrace:

#0  0x00000037c42897fb in memcpy () from /lib64/libc.so.6
#1  0x00007ffff79217b4 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long, unsigned long, unsigned long) ()
    at /home/myuser/install-c++11/build-dir/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/char_traits.h:290
#2  0x00007ffff7921826 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_leak_hard() ()
    at /home/myuser/install-c++11/build-dir/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.tcc:902
#3  0x00007ffff7bef6cc in boost::filesystem::path::m_append_separator_if_needed() () from /home/myuser/local/lib/libboost_filesystem.so.1.60.0
#4  0x00007ffff7bef76f in boost::filesystem::path::operator/=(boost::filesystem::path const&) () from /home/myuser/local/lib/libboost_filesystem.so.1.60.0
#5  0x00007ffff7bed472 in boost::filesystem::detail::directory_iterator_construct(boost::filesystem::directory_iterator&, boost::filesystem::path const&, boost::system::error_code*) ()
   from /home/myuser/local/lib/libboost_filesystem.so.1.60.0
#6  0x0000000000402c17 in boost::filesystem::directory_iterator::directory_iterator(boost::filesystem::path const&) ()
#7  0x0000000000402488 in main ()

The shared objects found by the executable are:

% LD_LIBRARY_PATH=$HOME/local/lib64:$HOME/local/lib ldd ./a.out
        linux-vdso.so.1 =>  (0x00007fffa21e0000)
        libboost_system.so.1.60.0 => /home/myuser/local/lib/libboost_system.so.1.60.0 (0x00007f4775468000)
        libboost_filesystem.so.1.60.0 => /home/myuser/local/lib/libboost_filesystem.so.1.60.0 (0x00007f4775250000)
        libstdc++.so.6 => /home/myuser/local/lib64/libstdc++.so.6 (0x00007f4774eb8000)
        libm.so.6 => /lib64/libm.so.6 (0x00000037c4600000)
        libgcc_s.so.1 => /home/myuser/local/lib64/libgcc_s.so.1 (0x00007f4774c88000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037c4200000)
        librt.so.1 => /lib64/librt.so.1 (0x00000037c5600000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00000037c4a00000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037c3e00000)

System info:

% uname -a
Linux my.sharedhost.com 3.12.50-39.ELK6.x86_64 #1 SMP Mon Nov 2 03:10:26 CST 2015 x86_64 x86_64 x86_64 GNU/Linux
mooiamaduck
  • 2,066
  • 12
  • 13
  • I can't easily validate the huge list of -B, -I, -L flags. I suggest to reduce to the minimum. Also, consider the `-Wl,rpath` option instead of LD_LIBRARY_PATH (see e.g. http://stackoverflow.com/questions/22312653/how-to-compile-boost-async-client-cpp/22313790#22313790) – sehe Jan 10 '16 at 02:27
  • Use -E to get the preprocessor output from your compilation step, then grep the preprocessed output for the paths to all the included files, to make sure that you're not picking up something a system include instead of your local one, for some reason. – Sam Varshavchik Jan 10 '16 at 02:33
  • I'm able to remove all of the `-I` and `-L` flags and get the same result. Only the `-B` flags are necessary. As for the included files, I can see when using the `-M` flag that libc headers come from `/usr/include`. However, I would expect that to be just fine since the libc runtime is being found under `/lib64/`. – mooiamaduck Jan 10 '16 at 02:38
  • @sehe I was able to compile the program with the `-Wl,-rpath` option, and `ldd` shows that the executable uses the local shared objects, but the program still segfaults, same as before. – mooiamaduck Jan 10 '16 at 02:47
  • Have you checked where the segfault occurs? See [this](http://stackoverflow.com/questions/8305866/how-to-analyze-a-programs-core-dump-file-with-gdb) if you're unfam7liar with gdb – user3159253 Jan 10 '16 at 04:05
  • @user3159253 `memcpy` in libc. – mooiamaduck Jan 10 '16 at 04:24
  • @user3159253 See backtrace in the original post. – mooiamaduck Jan 10 '16 at 04:26

0 Answers0