【发布时间】:2019-11-06 09:16:59
【问题描述】:
我遇到了一种非常奇怪的行为,我将其浓缩为一个非常基本的测试:
#include <string>
#include <filesystem>
int main(void)
{
const std::string name = "foo";
const std::filesystem::path lock_dir = "/tmp";
std::filesystem::path lockfile = lock_dir / name;
return 0;
}
我用g++ -std=c++17 -Wall -Wextra -Werror -g foo.cpp -o foo 编译这个。当我运行它时,我在附加两个路径的行上得到一个 std::bad_alloc 异常。这是我使用 gdb 看到的内容
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff742c801 in __GI_abort () at abort.c:79
#2 0x00007ffff7a8e1f2 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7a99e36 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7a99e81 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7a9a0b5 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff7a907a7 in std::__throw_bad_alloc() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x0000555555558cfe in __gnu_cxx::new_allocator<std::filesystem::__cxx11::path::_Cmpt>::allocate (this=0x7fffffffe080, __n=12297828079348111650) at /usr/include/c++/8/ext/new_allocator.h:102
#8 0x00005555555587d0 in std::allocator_traits<std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::allocate (__a=..., __n=12297828079348111650) at /usr/include/c++/8/bits/alloc_traits.h:436
#9 0x0000555555557f76 in std::_Vector_base<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::_M_allocate (this=0x7fffffffe080, __n=12297828079348111650)
at /usr/include/c++/8/bits/stl_vector.h:296
#10 0x0000555555558387 in std::_Vector_base<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::_M_create_storage (this=0x7fffffffe080, __n=12297828079348111650)
at /usr/include/c++/8/bits/stl_vector.h:311
#11 0x00005555555579cf in std::_Vector_base<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::_Vector_base (this=0x7fffffffe080, __n=12297828079348111650, __a=...)
at /usr/include/c++/8/bits/stl_vector.h:260
#12 0x0000555555556d39 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::vector (this=0x7fffffffe080,
__x=std::vector of length -1303124922760, capacity -1303124922760 = {...}) at /usr/include/c++/8/bits/stl_vector.h:460
#13 0x000055555555635f in std::filesystem::__cxx11::path::path (this=0x7fffffffe060, Python Exception <class 'gdb.error'> There is no member or method named _M_t.:
__p=...) at /usr/include/c++/8/bits/fs_path.h:166
#14 0x00005555555563c8 in std::filesystem:: (Python Exception <class 'gdb.error'> There is no member or method named _M_t.:
__lhs=..., Python Exception <class 'gdb.error'> There is no member or method named _M_t.:
__rhs=...) at /usr/include/c++/8/bits/fs_path.h:554
#15 0x0000555555555fbe in main () at foo.cpp:8
这带来了几个问题:
- 我的测试代码有什么问题?
- 为什么 GDB 在调用堆栈中使用 python 显示任何内容?
预料到这个问题,我的 g++ 是 gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1~18.04.1),我的 gdb 是 GNU gdb (Ubuntu 8.2-0ubuntu1~18.04) 8.2
UPDATE这是成功编译的可执行文件的ldd输出
linux-vdso.so.1 (0x00007ffc697b2000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5c35444000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5c3522c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5c34e3b000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5c34a9d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5c35a2d000)
【问题讨论】:
-
在编译/链接的时候加上
-lstdc++fs有什么不同吗? -
@TedLyngmo 没有它,他会遇到链接问题。
-
我想知道如何在没有
-lstdc++fs的情况下使用 gcc 8.3.0 进行编译。它应该失败...:-/ -
这里是另一个数据点。在我坏的虚拟机中,我可以用
g++ -std=c++17 -Wall -Wextra -Werror -g foo.cpp -o foo编译/链接一个坏的可执行文件。当我使用g++ -std=c++17 -Wall -Wextra -Werror -g foo.cpp -o foo -lstdc++fs编译/链接时,它运行没有问题 -
@TedLyngmo 您上面的 cmets 是正确的,如果不是 Ubuntu 的“功能”,它将是 100% 正确的。 Ubuntu 为 libstdc++ 提供不一致的标头和共享库是设计使然,这就是程序链接时不使用
-lstdc++fs的原因,这就是它在运行时崩溃的原因。请参阅下面的答案以获取更多信息。
标签: c++ exception gdb c++17 libstdc++