带 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 中得到修复。)
我有这个示例代码:
# 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 中得到修复。)