Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

c++ - Passing std::filesystem::path to a function segfaults

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...