带 flto 的 RHEL 8 上的 C++ 字符串段错误(但不是 RHEL 7)

C++ String Segfault on RHEL 8 with flto (but not RHEL 7)

我有这个示例代码:

# CMakeLists.txt

cmake_minimum_required(VERSION 3.18)
project(RHBuildTest CXX)

message(STATUS "C++ Compiler: ${CMAKE_CXX_COMPILER}")

add_executable(script1 script1.cpp)
set_target_properties(script1 PROPERTIES COMPILE_FLAGS "-flto")
// script1.cpp

#include <string>
#include <iostream>

int main()
{
    const std::string msg = "this is a string";

    std::cout << "msg.size():    " << msg.size() << "\n";
    std::cout << "msg:           " << msg << "\n";
    std::cout << "msg.substr(0): " << msg.substr(0) << "\n";

    return 0;
}

我们现在在 RHEL 7 和 RHEL 8 上针对 g++ 10.2.0 进行编译,但 RHEL 8 给出了 segault。如果我们去掉 -flto,那么 RHEL 8 就可以正常运行了。这是 ABI 问题吗?我是否需要设置某些路径以便加载正确的标准库(使用 -flto 时)?是什么导致了这个问题?


RHEL 7:

[~/code/rh_build_test/build_rh7]$ cat /etc/redhat-release; cmake ..; make; ./script1
Red Hat Enterprise Linux Server release 7.7 (Maipo)
-- C++ Compiler: /app/.../el7.3.10/x86_64-gcc10.2.x/gcc-10.2.0/bin/g++
-- Configuring done
-- Generating done
-- Build files have been written to: ~/code/rh_build_test/build_rh7
[ 50%] Building CXX object CMakeFiles/script1.dir/script1.cpp.o
[100%] Linking CXX executable script1
[100%] Built target script1
msg.size():    16
msg:           this is a string
msg.substr(0): this is a string

RHEL 8:

[~/code/rh_build_test/build_rh8]$ cat /etc/redhat-release; cmake ..; make; ./script1
Red Hat Enterprise Linux release 8.4 (Ootpa)
-- C++ Compiler: /app/.../el8_4.4.18/x86_64-gcc10.2.x/gcc-10.2.0/bin/g++
-- Configuring done
-- Generating done
-- Build files have been written to: ~/code/rh_build_test/build_rh8
[ 50%] Building CXX object CMakeFiles/script1.dir/script1.cpp.o
[100%] Linking CXX executable script1
[100%] Built target script1
Segmentation fault (core dumped)

有时 RHEL 8 打印多一点,但总是在 substr:

处失败
...
[100%] Built target script1
msg.size():    16
msg:           this is a string
Segmentation fault (core dumped)

这是 RHEL 中的已知错误:Segfault when -flto is used to compile Catch framework tests on RHEL 8.4

要确认您 运行 遇到的是同一个错误,请查看将 binutils 暂时降级到 2.30-79.el8 是否可以正常工作。如果是这样,那么看起来它会在 RHEL 8.5 发布时得到妥善修复。 (编辑:我刚刚确认这确实在与 RHEL 8.5 一起发布的 binutils 2.30-108 中得到修复。)