C Строка Segfault в RHEL 8 с flto (но не в RHEL 7)

#c #string #segmentation-fault #redhat

Вопрос:

У меня есть этот пример кода:

 # 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;
}
 

Теперь мы компилируем против g 10.2.0 на RHEL 7 и RHEL 8, но 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)
 

Комментарии:

1. Нет никакой гарантии, если только поставщик не говорит как таковой, что внутренние std::string компоненты одинаковы между версиями компилятора. Это верно для любого компилятора, не говоря уже о g . Таким образом, вы должны использовать соответствующую библиотеку.

2. @PaulMcKenzie Это именно мой вопрос, как мне убедиться, что используется «подходящая библиотека»?

3. Это похоже на ошибку внутреннего компилятора или компоновщика. Поскольку вы используете RHEL, у вас должен быть контракт на поддержку с Red Hat. Соответственно, вы должны подать сообщение об ошибке в Red Hat, и пусть они разберутся в этом.

Ответ №1:

Это известная ошибка в RHEL: Segfault, когда-flto используется для компиляции тестов Catch framework в RHEL 8.4

Чтобы подтвердить, что это та же ошибка, с которой вы столкнулись, посмотрите, работает ли временное понижение binutils до 2.30-79.el8. Если это так, то, похоже, это будет исправлено должным образом, когда будет выпущен RHEL 8.5. (ПРАВКА: я только что подтвердил, что это действительно исправлено в binutils 2.30-108, который был выпущен с RHEL 8.5.)