Red Hat Training

A Red Hat training course is available for RHEL 8

16장. 컴파일러 및 개발 도구

16.1. RHEL 7 이후 툴체인 변경

다음 섹션에서는 Red Hat Enterprise Linux 7에서 설명된 구성 요소 릴리스 이후 툴체인의 변경 사항을 나열합니다. Red Hat Enterprise Linux 8.0 릴리스 노트 도 참조하십시오.

16.1.1. RHEL 8 GCC의 변경 사항

Red Hat Enterprise Linux 8에서 GCC 툴체인은 GCC 8.2 릴리스 시리즈를 기반으로 합니다. Red Hat Enterprise Linux 7 이후 주요 변경 사항은 다음과 같습니다.

  • 별칭 분석, vectorizer 개선, 동일한 코드 접기, 비 절차 분석, 저장 최적화 패스 및 기타와 같은 일반적인 최적화가 많이 추가되었습니다.
  • 주소 로티가 개선되었습니다.
  • 메모리 누수 감지를 위한 Leak Sanitizer가 추가되었습니다.
  • 정의되지 않은 동작을 감지하기 위한 Undefined Behavior Sanitizer가 추가되었습니다.
  • 디버그 정보는 이제 DWARF5 형식으로 생성할 수 있습니다. 이 기능은 실험적입니다.
  • 소스 코드 적용 분석 도구 GCOV는 다양한 개선 사항으로 확장되었습니다.
  • OpenMP 4.5 사양 지원이 추가되었습니다. 또한 OpenMP 4.0 사양의 오프로드 기능은 이제 C, C++ 및 Fortran 컴파일러에서 지원됩니다.
  • 새로운 경고와 향상된 진단이 특정 프로그래밍 오류를 정적 탐지하기 위해 추가되었습니다.
  • 이제 소스 위치가 포인트가 아닌 범위로 추적되어 훨씬 풍부한 진단을 수행할 수 있습니다. 컴파일러는 이제 "고정" 힌트를 제공하여 가능한 코드 수정을 제안합니다. 맞춤법 검사기가 추가되어 대체 이름을 제공하고 오타를 쉽게 감지할 수 있습니다.

보안

GCC는 생성된 코드를 추가로 강화할 수 있는 도구를 제공하기 위해 확장되었습니다. 보안과 관련된 개선 사항은 다음과 같습니다.

  • 오버플로 검사를 사용하는 산술 작업에 대한 __builtin_add_overflow,__builtin_sub_overflow, __builtin_mul_overflow 기본 제공 함수가 추가되었습니다.
  • 스택 충돌에 대한 추가 코드 보호 기능을 생성하기 위해 -fstack-clash-protection 옵션이 추가되었습니다.
  • -fcf-protection 옵션은 프로그램 보안 향상을 위해 control-flow 명령의 대상 주소를 확인하기 위해 도입되었습니다.
  • 새로운 -Wstringop-truncation 경고 옵션은 복사된 문자열을 잘라내거나 대상을 변경하지 않은 상태로 두는 strncat,strncpy 또는 stpncpy 와 같은 바인딩된 문자열 조작 기능에 대한 호출을 나열합니다.
  • -Warray-bounds 경고 옵션은 범위를 벗어난 배열 인덱스 및 포인터 오프셋을 더 잘 감지하도록 개선되었습니다.
  • memcpy 또는 realloc 와 같은 원시 메모리 액세스 기능을 통해 비공식 클래스 유형의 객체를 잠재적으로 안전하지 않은 조작에 대해 경고하기 위해 -Wclass-memaccess 경고 옵션이 추가되었습니다.

아키텍처 및 프로세서 지원

아키텍처 및 프로세서 지원 개선 사항은 다음과 같습니다.

  • Intel AVX-512 아키텍처에 대한 여러 가지 새로운 아키텍처, 여러 마이크로 아키텍처 및 Intel SGX(Software guard Extensions)가 추가되었습니다.
  • 코드 생성은 이제 64 비트 ARM ARM 아키텍처 LSE 확장, ARMv8.2-A (FPE), ARMv8.2-A, ARMv8.3-A, ARMv8.4-A 아키텍처 버전을 대상으로 할 수 있습니다.
  • ARM 및 64비트 ARM 아키텍처의 -march=native 옵션이 수정되었습니다.
  • 64비트 IBM Z 아키텍처의 z13 및 z14 프로세서에 대한 지원이 추가되었습니다.

언어 및 표준

언어 및 표준과 관련된 주요 변경 사항은 다음과 같습니다.

  • C 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장을 사용하여 C17으로 변경되었습니다.
  • C++ 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장 기능을 사용하여 C++14로 변경되었습니다.
  • 이제 C++ 런타임 라이브러리에서 C++11 및 C++14 표준을 지원합니다.
  • C++ 컴파일러는 이제 변수 템플릿과 같은 많은 새로운 기능을 통해 C++14 표준을 구현하고, 비정적 데이터 멤버 초기화기, 확장된 constexpr ator, sized deallocation 함수, 일반 람다, 변수 길이 배열, 숫자 구분 기호 등을 사용하여 C++14 표준을 구현합니다.
  • C 언어 표준 C11 지원이 개선되었습니다. ISO C11 원자성, 일반적인 선택 사항 및 스레드 로컬 스토리지를 사용할 수 있습니다.
  • 새로운 __auto_type GNU C 확장은 C 언어의 C++11 auto 키워드의 기능의 서브셋을 제공합니다.
  • ISO/IEC TS 18661-3:2015 표준에 지정된 _FloatN x 및 _FloatNx 유형 이름은 이제 C 프런트 엔드에서 인식합니다.
  • C 언어로 코드를 컴파일할 때 사용되는 기본 표준은 GNU 확장을 사용하여 C17으로 변경되었습니다. 이는 --std=gnu17 옵션을 사용하는 것과 동일한 효과가 있습니다. 이전에는 기본값이 GNU 확장을 사용하는 C89였습니다.
  • GCC는 이제 C++17 언어 표준과 C++20 표준의 특정 기능을 사용하여 코드를 실험적으로 컴파일할 수 있습니다.
  • 이제 빈 클래스를 인수로 전달하면 플랫폼 ABI에 필요한 대로 Intel 64 및 AMD64 아키텍처에서 공간을 차지하지 않습니다. 삭제된 복사본만 사용하여 클래스를 전달하거나 반환하거나 생성자를 이동해도 생성자가 아닌 복사 또는 이동 생성자가 있는 클래스와 동일한 호출 규칙을 사용합니다.Passing or returning a class with only deleted copy and move constructors now uses the same calling convention as a class with a non-trivial copy or move constructor.
  • C++11 alignof 연산자에서 반환된 값은 C _Alignof 연산자와 일치하도록 수정되었으며 최소 정렬을 반환하도록 수정되었습니다. 선호하는 정렬을 찾으려면 GNU 확장자 __alignof__ 를 사용합니다.
  • Fortran 언어 코드의 libgfortran 라이브러리의 기본 버전이 5로 변경되었습니다.
  • Ada (GNAT), GCC Go 및 후에 C/C++ 언어에 대한 지원이 제거되었습니다. Go 코드 개발에 Go Toolset을 사용합니다.

추가 리소스

16.1.2. RHEL 8의 GCC 보안 개선

다음은 보안과 관련된 GCC의 변경 사항이며 Red Hat Enterprise Linux 7.0 릴리스 이후 추가되었습니다.

새 경고

이러한 경고 옵션이 추가되었습니다.

옵션경고 표시

-Wstringop-truncation

복사된 문자열을 잘라내거나 대상을 변경하지 않고 그대로 유지할 수 있는 strncat,strncpystpncpy 와 같은 바인딩된 문자열 조작 함수를 호출합니다.

-Wclass-memaccess

비독점 클래스 유형의 개체는 memcpy 또는 realloc 와 같은 원시 메모리 기능에 의해 잠재적으로 안전하지 않은 방식으로 조작됩니다.

경고는 사용자 정의 생성자 또는 복사 할당 연산자를 바이패스하는 호출, 손상된 가상 테이블 포인터, const-qualified 형식 또는 참조 또는 멤버 포인터의 데이터 멤버를 감지하는 데 도움이 됩니다. 경고는 데이터 멤버에 대한 액세스 제어를 바이패스하는 호출도 감지합니다.

-Wmisleading-indentation

코드의 들여쓰기를 통해 코드의 블록 구조를 사람이 리더에게 잘못된 정보를 제공할 수 있는 위치에 위치합니다.

-Walloc-size-larger-than=size

메모리를 할당할 메모리의 크기가 초과된 메모리 할당 기능에 대한 호출입니다. 두 매개 변수를 곱하여 할당이 지정된 함수와 속성 alloc_size 로 장식된 모든 함수와 함께 작동합니다.

-Walloc-zero

제로 양의 메모리를 할당하려는 메모리 할당 함수에 대한 호출입니다. 두 매개 변수를 곱하여 할당이 지정된 함수와 속성 alloc_size 로 장식된 모든 함수와 함께 작동합니다.

-Walloca

alloca 함수를 호출합니다.

-Walloca-larger-than=size

요청된 메모리가 크기 보다 많은 alloca 함수에 대한 호출입니다.

-Wvla-larger-than=size

지정된 크기를 초과하거나 바인딩된 값을 충분히 제한할 수 없는 변수 길이 배열(VLA)입니다.

-Wformat-overflow=level

포맷된 출력 함수의 stekton 제품군에 대한 호출의 특정 및 가능성이 있는 버퍼 오버플로우입니다.Both certain and likely buffer overflow in calls to the soctets family of formatted output functions. 수준 값에 대한 자세한 내용과 설명은 gcc(1) 매뉴얼 페이지를 참조하십시오.

-Wformat-truncation=level

포맷된 출력 함수의 sntekton 제품군에 대한 호출의 특정 출력 well 및 가능한 출력 well입니다. 수준 값에 대한 자세한 내용과 설명은 gcc(1) 매뉴얼 페이지를 참조하십시오.

-Wstringop-overflow=type

memcpystrcpy 와 같은 문자열 처리 기능에 대한 호출의 버퍼 오버플로 수준 값에 대한 자세한 내용과 설명은 gcc(1) 매뉴얼 페이지를 참조하십시오.

경고 개선 사항

이러한 GCC 경고가 개선되었습니다.

  • -Warray-bounds 옵션은 아웃 바운드(out-of-bound) 배열 인덱스 및 포인터 오프셋의 더 많은 인스턴스를 감지하도록 개선되었습니다. 예를 들어 음수 또는 과도한 인덱스를 유연한 배열 멤버로 변환하고 문자열 리터럴이 탐지됩니다.
  • GCC 7에 도입된 -Wrestrict 옵션은 memcpystrcpy 와 같은 표준 메모리 및 문자열 조작 기능에 대한 제한 인수를 통해 개체에 대한 더 많은 중복 액세스 인스턴스를 감지하도록 개선되었습니다.
  • -Wnonnull 옵션은 null 포인터를 null이 아닌 인수(null이 아닌 속성과 함께 있음)를 예상하는 함수에 전달하는 광범위한 사례를 감지하도록 개선되었습니다.

새로운 UndefinedBehaviorSanitizer

UndefinedBehaviorSanitizer라는 정의되지 않은 동작을 감지하는 새로운 런타임 sanitizer가 추가되었습니다. 다음 옵션은 주목할 가치가 있습니다.

옵션Check

-fsanitize=float-divide-by-zero

부동 소수점 분할을 0으로 감지합니다.

-fsanitize=float-cast-overflow

정수 변환에 부동 소수점 유형의 결과가 오버플로되지 않는지 확인합니다.

-fsanitize=bounds

배열 경계를 계측하고 범위를 벗어난 액세스를 감지할 수 있습니다.

-fsanitize=alignment

맞춤 검사를 활성화하고 다양한 잘못 정렬된 오브젝트를 감지할 수 있습니다.

-fsanitize=object-size

개체 크기 검사를 활성화하고 다양한 범위를 벗어난 액세스를 감지합니다.

-fsanitize=vptr

C++ 멤버 함수 호출, 멤버 액세스 및 포인터 간 일부 변환을 기본 클래스와 파생된 클래스로 검사할 수 있습니다.Enables checking of C++ member function calls, member accesses, and some conversions between pointers to base and derived classes. 또한 참조된 오브젝트에 올바른 동적 유형이 없는 경우 탐지됩니다.

-fsanitize=bounds-strict

배열 경계를 엄격하게 확인할 수 있습니다. 이렇게 하면 -fsanitize=bounds 및 flexible array 멤버와 같은 배열의 계측을 활성화합니다.

-fsanitize=signed-integer-overflow

일반 벡터를 사용하여 산술 연산에서도 산술 오버플로를 진단합니다.

-fsanitize=builtin

런타임에 잘못된 인수 __builtin_clz 또는 __builtin_ctz 접두사 내장된 인수를 진단합니다. -fsanitize=undefined 의 검사를 포함합니다.

-fsanitize=pointer-overflow

포인터 줄 바꿈을 위해 저렴한 런타임 테스트를 수행합니다. -fsanitize=undefined 의 검사를 포함합니다.

AddressSanitizer에 대한 새로운 옵션

이러한 옵션은 AddressSanitizer에 추가되었습니다.

옵션Check

-fsanitize=pointer-compare

다른 메모리 개체를 가리키는 포인터의 비교에 대해 경고합니다.

-fsanitize=pointer-subtract

다른 메모리 오브젝트를 가리키는 포인터의 빼기에 대해 경고합니다.

-fsanitize-address-use-after-scope

변수가 정의된 범위 후에 주소를 사용하고 사용하는 변수를 삭제합니다.

기타 과성자 및 계측

  • 스택 공간이 정적으로 할당되거나 동적으로 스택 오버플로를 감지하기 위해 -fstack-clash-protection 옵션을 삽입하여 스택 오버플로를 안정적으로 탐지하고 운영 체제에서 제공하는 스택 보호 페이지를 건너뛰는 공격 벡터를 완화합니다.
  • 새로운 옵션 -fcf-protection=[full|branch|return|none] 이 추가되어 코드 계측을 수행하고 control-flow 전송 명령(예: 간접 함수 호출, 함수 반환, 간접 점과 같은)의 대상 주소가 유효한지 확인하여 프로그램 보안을 높일 수 있습니다.

추가 리소스

  • 위의 일부 옵션에 제공된 값에 대한 자세한 내용과 설명은 gcc(1) 매뉴얼 페이지를 참조하십시오.

    $ man gcc

16.1.3. RHEL 8 GCC의 호환성 발생 변경

C++ ABI는 std::stringstd::list에서 변경

libstdc++ 라이브러리의 std:: string 및 std::list 클래스의 ABI(Application Binary Interface)는 RHEL 7 (GCC 4.8)과 RHEL 8(GCC 8) 사이에서 C++11 표준을 준수하도록 변경되었습니다. libstdc++ 라이브러리는 이전 및 새 ABI를 모두 지원하지만 다른 C++ 시스템 라이브러리는 지원하지 않습니다. 결과적으로 이러한 라이브러리에 대해 동적으로 연결되는 애플리케이션을 다시 빌드해야 합니다. 이는 C++98을 포함한 모든 C++ 표준 모드에 영향을 미칩니다. 또한 RHEL 7용 Red Hat Developer Toolset 컴파일러를 사용하여 빌드된 애플리케이션에도 영향을 미치므로 시스템 라이브러리와의 호환성을 유지하기 위해 이전 ABI가 유지되었습니다.

GCC는 더 이상 Ada, Go, Obspi C/C++ 코드를 빌드하지 않습니다.

Ada (GNAT), GCC Go 및 intended C/C++ 언어로 코드를 빌드하는 기능이 GCC 컴파일러에서 제거되었습니다.

Go 코드를 빌드하려면 대신 Go Toolset을 사용합니다.