LTO导致标准库崩溃 [英] LTO causes crash in standard library

查看:169
本文介绍了LTO导致标准库崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下程序:

#include <iostream>
#include <string>

int main()
{
        std::string s;
        std::getline(std::cin, s);
        return 0;
}

我尝试使用各种标志来构建它并以 echo foo |./prog.

I try to build it with various flags and run as echo foo | ./prog.

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

If I build it with clang 5.0 or gcc 7.1 (or 7.2) with optimization from -O0 to -O3, it works as expected. But if I add -flto to any of these configurations, it crashes immediately with the following backtrace:

/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_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_ES4_+0x175)[0x7f596b984c05]
./a.out[0x400d7d]
./a.out[0x400c32]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f596b03c6e5]
./a.out[0x400ab9]

Valgrind以更易读的方式报告相同内容:

Valgrind reports the same in a slightly more readable way:

==30863== Invalid free() / delete / delete[] / realloc()
==30863==    at 0x4C2A8DC: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==30863==    by 0x4F0E054: std::string::reserve(unsigned long) (in /usr/lib64/libstdc++.so.6.0.24)
==30863==    by 0x4EE6C04: std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) (in /usr/lib64/libstdc++.so.6.0.24)
==30863==    by 0x40091B: main (in /path/to/prog)
==30863==  Address 0x6011c0 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE"

即使启用了LTO,它也可以在-std = c ++ 14 及以下版本中正常工作.

Also it works OK with --std=c++14 and below even with LTO enabled.

那是什么问题?在两个编译器中的C ++ 17的LTO实现中是否都存在错误?还是只是 libstdc ++ 用错误的标志进行编译?我使用opensuse 42.3,并且从存储库中安装了标准库.

So what is the problem? Is it a bug in LTO implementation for C++17 in both compilers? Or just the libstdc++ is compiled with wrong flags? I use opensuse 42.3 and the standard library is installed from repositories.

可以以某种方式解决此问题吗?

Can it be worked around somehow?

推荐答案

对于gcc,它看起来像是这样的错误: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82172 .

For gcc this looks like this bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82172.

有多种解决方法,请参见 https://gcc.gnu.org/bugzilla/show_bug.cgi?id = 82172#c3 .其中之一是使用 -D_GLIBCXX_USE_CXX11_ABI = 1 :

There are a number of workarounds, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82172#c3. One of them is to use -D_GLIBCXX_USE_CXX11_ABI=1:

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

在此处也请参见相同的问题 flto因gcc7.2崩溃.

See also the same problem here flto crash with gcc7.2.

这篇关于LTO导致标准库崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆