Passing std::filesystem::path to a function segfaults
Asked Answered
H

3

14

When I attempt to use std::filesystem::path as a function argument, it segfaults on my machine. Here is a minimal example:

#include <filesystem>

void thing(const std::filesystem::path& p) {
    return;
}

int main() {
    thing("test");
    return 0;
}

This snippet results in the following backtrace from gdb:

#0  0x0000563a5a3814b3 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::~vector (this=0x23, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:567
#1  0x0000563a5a38132c in std::filesystem::__cxx11::path::~path (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:208
#2  0x0000563a5a381f74 in std::filesystem::__cxx11::path::_Cmpt::~_Cmpt (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:643
#3  0x0000563a5a381f8f in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt> (__pointer=0x3) at /usr/include/c++/8/bits/stl_construct.h:98
#4  0x0000563a5a381e3f in std::_Destroy_aux<false>::__destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:108
#5  0x0000563a5a381ab0 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:137
#6  0x0000563a5a3817c1 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*, std::filesystem::__cxx11::path::_Cmpt> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:206
#7  0x0000563a5a3814c9 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::~vector (this=0x7ffd198df8a0 = {...}, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:567
#8  0x0000563a5a38132c in std::filesystem::__cxx11::path::~path (this=0x7ffd198df880<error reading variable: Cannot access memory at address 0x2b>, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:208
#9  0x0000563a5a381247 in main () at /home/user/CLionProjects/test/main.cpp:8
#10 0x00007fd6bb96ab6b in __libc_start_main (main=0x563a5a381200 <main()>, argc=1, argv=0x7ffd198df9b8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd198df9a8) at ../csu/libc-start.c:308
#11 0x0000563a5a38113a in _start ()

I am using GCC 8.3 on Ubuntu 19.10, I had someone else compile and run this code with no issues on Windows so it could potentially be a bug in libstdc++

Hen answered 16/6, 2019 at 3:29 Comment(1)
Ubuntu 19.10 won't be out until October, presumably you mean 18.10?Indus
X
18

I think the problem is that Ubuntu mixes GCC versions in a single installation. On Ubuntu the default GCC is version 8, but the libstdc++.so.6 library comes from GCC 9. With GCC 8 the std::filesystem definitions are in a separate library, libstdc++fs.a, which must be linked to explicitly. In GCC 9 the std::filesystem symbols are in the main libstdc++.so library. Because of the mixed up Ubuntu installation it's possible for the GCC 9 symbols in libstdc++.so to satisfy the undefined references in code compiled with GCC 8 which should be satisfied by libstdc++fs.a. Because the std::filesystem symbols in GCC 9 are incompatible with the experimental versions of those symbols in GCC 8, it appears to link OK but crashes at runtime.

It should work correctly if you make sure you link with -lstdc++fs and make sure that option comes after all your object files, e.g. this should work:

g++ foo.o bar.o -lstdc++fs

But this will not work:

g++ -lstdc++fs foo.o bar.o

There is supposed to be an update to the Ubuntu gcc-8 packages to fix this, by ensuring the -lstdc++fs option comes after all the other input files. For more details see https://bugs.launchpad.net/ubuntu/+source/gcc-8/+bug/1824721

Compiling with gcc-9 also works, because when using GCC 9 to compile there is no need to link to -lstdc++fs for std::filesystem (with GCC 9 it's only needed for std::experimental::filesystem symbols).

Xerxes answered 3/7, 2019 at 7:15 Comment(0)
H
1

I was able to fix this issue by installing GCC and G++ 9 from this PPA: https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test

Hen answered 16/6, 2019 at 5:0 Comment(1)
Using G++9 worked for me too sudo apt install g++-9 on 19.04 without this PPA. Also removed g++8 and updated the g++ alternatives list sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 10Food
A
1

Please link -lstdc++fs library, let's consider source file is fileSys.cpp then compile it as follows,
g++ -std=c++17 fileSys.cpp -lstdc++fs -o fs

I am using GCC 8.1.0 and Ubuntu 16.04.1 LTS.
There is already a similar question on this topic, you can find it at filesystem linker error

Antiperiodic answered 16/6, 2019 at 7:37 Comment(4)
@AlanBirtles: So you can compile it successfully without linking stdc++fs library?Antiperiodic
I haven't tried but the OP has posted a runtime error so he must be able to link correctlyIndus
Please try to compile it without linking stdc++fs library.Antiperiodic
I'm sure it won't work but it's still not related to this questionIndus

© 2022 - 2024 — McMap. All rights reserved.