将 std::filesystem::path 传递给函数段错误
当我尝试使用 std::filesystem::path
作为函数参数时,它在我的机器上出现了段错误.这是一个最小的例子:
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;
}
此代码段导致 gdb 的以下回溯:
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 ()
我在 Ubuntu 19.10 上使用 GCC 8.3,我让其他人在 Windows 上编译并运行此代码没有问题,因此它可能是 libstdc++
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++
推荐答案
我认为问题在于 Ubuntu 在单个安装中混合了 GCC 版本.在 Ubuntu 上,默认的 GCC 是版本 8,但 libstdc++.so.6
库来自 GCC 9.对于 GCC 8,std::filesystem
定义位于单独的库中, libstdc++fs.a
,必须显式链接.在 GCC 9 中,std::filesystem
符号位于主 libstdc++.so
库中.由于混杂的 Ubuntu 安装,libstdc++.so
中的 GCC 9 符号可能满足用 GCC 8 编译的代码中的未定义引用,应该由 libstdc++fs.a
.由于 GCC 9 中的 std::filesystem
符号与 GCC 8 中这些符号的实验版本不兼容,因此它似乎可以链接,但在运行时崩溃.
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.
如果您确保与 -lstdc++fs
链接并确保该选项位于所有目标文件之后,它应该可以正常工作,例如这应该工作:
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
但这将不工作:
g++ -lstdc++fs foo.o bar.o
应该更新 Ubuntu gcc-8
包来解决这个问题,方法是确保 -lstdc++fs
选项出现在所有其他输入之后文件.有关详细信息,请参阅 https://bugs.launchpad.net/ubuntu/+source/gcc-8/+bug/1824721
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
使用 gcc-9
编译也可以,因为当使用 GCC 9 编译时,不需要为 std 链接到
(对于 GCC 9,它只需要 -lstdc++fs
::filesystemstd::experimental::filesystem
符号).
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).
相关文章