Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ LTO导致标准库崩溃_C++_Gcc_Segmentation Fault_Clang_Lto - Fatal编程技术网

C++ LTO导致标准库崩溃

C++ LTO导致标准库崩溃,c++,gcc,segmentation-fault,clang,lto,C++,Gcc,Segmentation Fault,Clang,Lto,考虑以下计划: #包括 #包括 int main() { std::字符串s; 标准::getline(标准::cin,s); 返回0; } 我尝试用各种标志构建它,并作为echo foo |/prog运行 如果我使用clang 5.0或gcc 7.1(或7.2)构建它,并从-O0到-O3进行优化,那么它将按预期工作。但是如果我将-flto添加到这些配置中的任何一个,它会立即崩溃,并出现以下回溯: /lib64/libc.so.6(+0x721af)[0x7f596b08e1af] /lib6

考虑以下计划:

#包括
#包括
int main()
{
std::字符串s;
标准::getline(标准::cin,s);
返回0;
}
我尝试用各种标志构建它,并作为
echo foo |/prog
运行

如果我使用clang 5.0或gcc 7.1(或7.2)构建它,并从
-O0
-O3
进行优化,那么它将按预期工作。但是如果我将
-flto
添加到这些配置中的任何一个,它会立即崩溃,并出现以下回溯:

/lib64/libc.so.6(+0x721af)[0x7f596b08e1af]
/lib64/libc.so.6(+0x77706)[0x7f596b093706]
/lib64/libc.so.6(+0x78453)[0x7f596b094453]
/usr/lib64/libstdc++.so.6(_ZNSs7reserveEm+0x85)[0x7f596b9ac055]
/usr/lib64/libstdc++.so.6(_ZSt7getlineIcSt11char_traitssiceeerst13basic_istreamIT_ES7_RSbIS4_S5_T1_ES4_+0x175)[0x7f596b984c05]
/a.out[0x400d7d]
/a.out[0x400c32]
/lib64/libc.so.6(u libc_start_main+0xf5)[0x7f596b03c6e5]
/a.out[0x400ab9]
Valgrind以更具可读性的方式报告了同样的情况:

==30863==Invalid free()/delete/delete[]/realloc()
==30863==at 0x4C2A8DC:运算符删除(void*)(在/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so中)
==30863==by 0x4F0E054:std::string::reserve(无符号长)(in/usr/lib64/libstdc++.so.6.0.24)
==30863==0x4EE6C04:std::basic_istream&std::getline(std::basic_istream&,std::basic_string&,char)(in/usr/lib64/libstdc++.so.6.0.24)
==30863==by 0x40091B:main(in/path/to/prog)
==30863==地址0x6011c0是数据符号“\u ZNSs4\u Rep20\u S\u empty\u rep\u storage”内的0字节
即使启用了LTO,它在
--std=c++14
及以下版本也可以正常工作

那么问题是什么呢?这是两个编译器中C++17的LTO实现中的错误吗?或者仅仅是
libstdc++
用错误的标志编译?我使用opensuse 42.3,标准库是从存储库安装的


它能以某种方式解决吗?

对于gcc,这看起来像是一个错误:

有许多变通方法,请参阅。其中之一是使用
-D\u GLIBCXX\u使用\u cx11\u ABI=1

g++ -D_GLIBCXX_USE_CXX11_ABI=1 --std=c++17 -flto prog.cpp

这里也可以看到同样的问题。

在ks1322的链接之后,我终于找到了binutils bug,它 描述问题的根源

该错误最终在binutils 2.30中修复,并后移植到binutils 2.29和2.28。更新到binutils 2.29修复了测试示例,但我的实际构建仍然受到影响


我发现我的项目的一个依赖项(我使用CMake和)是在没有LTO的情况下构建的。向所有依赖项添加
-flto
,并使用适当的归档程序(即
gcc ar
而不是
ar
)彻底解决了问题。

谢谢您的回答!你的链接为我指明了正确的方向,所以我最终解决了这个问题,并添加了我自己的答案和完整的描述。