全部產品
Search
文件中心

Alibaba Cloud Linux:Alibaba Cloud Linux 3和CentOS 8系統中GCC/Glibc的相容性對比說明

更新時間:Aug 15, 2024

本文介紹GCC/Glibc組件的相容性情況。從GCC 8到GCC10版本、Glibc 2.28到Glibc 2.32版本的重要變更,以及這些變更產生的前向或回溯相容性影響,同時也提出了相應的解決方案。

背景資訊

GCC/Glibc組件的相容性可分為ABI(Application Binary Interface)相容性和API(Application Programming Interface)相容性。對於GCC/Glibc的ABI相容性,主要指影響二進位直接啟動並執行相容性;而對於GCC/Glibc的API相容性,則主要指影響應用程式代碼編譯的相容性。

GCC/Glibc的ABI相容性

說明

GCC是一個編譯器,通常不涉及“ABI 相容性”的概念。然而,由於Alibaba Cloud Linux及CentOS等作業系統發行版會在GCC軟體包中搭載標準的C++庫(libstdc++),因此GCC對應用ABI相容性的影響,通常是指libstdc++庫對應用ABI相容性的影響。

  • 前向相容性:libstdc++Glibc都有良好的前向相容性,因此基於CentOS 8的GCC 8Glibc 2.28編譯的組件,大部分可以直接在Alibaba Cloud Linux 3的GCC 10Glibc 2.32環境中運行。

  • 回溯相容性:libstdc++Glibc都無法與舊版相容,因此基於Alibaba Cloud Linux 3的GCC 10Glibc 2.32編譯的組件無法直接在CentOS 8的GCC 8Glibc 2.28環境中運行。

GCC/Glibc的API相容性

GCCGlibc作為作業系統的核心工具鏈,對應用API有著良好的前與舊版相容。然而,在版本更新的過程中,也會出現影響應用API相容性的變更。

  • GCC

    • 影響前向相容性的樣本:低版本的GCC編譯參數在高版本中被廢棄,使用了相同編譯參數的應用程式無法在高版本的GCC環境中編譯通過,需要手動修改編譯參數。

    • 影響回溯相容性的樣本:高版本的GCC引入新的編譯參數,使用了該參數的應用程式無法直接在低版本的GCC環境中編譯通過,需要手動修改編譯參數。

  • Glibc

    • 影響前向相容性的樣本:低版本的Glibc函數或標頭檔在高版本中被廢棄,使用了該函數或標頭檔的應用程式無法在高版本的Glibc環境中編譯通過,需要手動修改應用程式代碼。

    • 影響回溯相容性的樣本:高版本的Glibc引入了新的函數及實現,使用了該函數的應用程式無法直接在低版本的Glibc環境中編譯通過,需要手動修改應用程式代碼。

Glibc 2.32版本的重要變更及影響

下表列出了Glibc 2.28Glibc 2.32版本的重要變更,並介紹了這些變更所帶來的影響以及相應的解決方案。

類別

變更

相容性變更類型

影響

解決方案

time

time.h中刪除了stime的聲明。

API

如果源碼使用了stime,會導致編譯報錯。

使用clock_settime代替stime

廢棄了ftime

API

如果源碼使用了ftime,會導致編譯報錯。

使用clock_gettime代替ftime

gettimeofday不再提供時區資訊。

API

gettimeofday無法擷取時區資訊。

使用clock_gettime代替gettimeofday

POSIX已經將settimeofday標記為過時狀態。

API

settimeofday無法同時設定時間和位移。

使用clock_settime/adjtime代替settimeofday

nanosleep使用的系統調用從nanosleep變更為clock_nanosleep

API

seccomp模式下啟動並執行應用程式,如果未將clock_nanosleep添加到白名單中,將導致應用程式調用nanosleep失敗。

添加clock_nanosleep到白名單中。

sysctl

刪除了標頭檔sys/sysctl.h

API

引用了該標頭檔的代碼會編譯失敗。

刪除代碼中對sys/sysctl.h的引用。

刪除了sysctl函數,sysctl僅作為相容符號存在。

API

調用sysctl介面直接返回ENOSYS

使用sysctl介面改為直接存取/proc/sys。擷取隨機位可通過getentropy函數擷取。

sstk

從標頭檔中刪除了sstk函式宣告。

ABI

基於舊版本Glibc編譯的應用程式,仍然保持ABI相容。如果程式調用了該函數,則會一直返回失敗,可能導致程式非預期的運行結果。

核心和Glibc已不再支援sstk,請刪除對sstk的調用。

API

對於新編譯的應用程式,會直接編譯失敗。

signal

傳統的訊號處理函數siginterruptsigpausesigholdsigrelsesigignoresigsetsigmask宏將被廢棄。

ABI

對於已編譯的二進位,libc.so仍然保持ABI相容。

無需解決方案。

API

對於應用程式代碼,編譯會出現warning或者error

修改源碼,使用sigsuspend/sigprocmask/sigaction函數代替。

<string.h>中刪除了sys_siglist_sys_siglistsys_sigabbrev的聲明。

ABI

對於已編譯的二進位,libc.so仍然保持ABI相容。

無需解決方案。

API

對於應用程式代碼,編譯會出現warning或者error

修改源碼,使用strsignal代替。

sys error

stdio.h中刪除了sys_errlist_sys_errlistsys_nerr_sys_nerr聲明。

ABI

對於已編譯的二進位,libc.so仍然保持ABI相容。

無需解決方案。

API

對於應用程式代碼,編譯會出現warning或者error

使用strerror/strerror_r代替。

copy_file_range

刪除了copy_file_range的類比實現。

API

應用程式調用copy_file_range時,如果核心不支援,該介面直接返回ENOSYS。

如果核心不支援copy_file_range,需應用程式自行實現copy_file_range功能。Alibaba Cloud Linux 3預設核心版本5.10,已支援copy_file_range

thread

新增<sys/single_threaded.h>,定義變數_libc_single_threaded

API

如果使用了弱引用libpthread的函數,如pthread_create/pthread_key_create的方法來檢測應用程式是否是單線程的做法已經過時。未來的Glibc版本會在libc.so.6中定義pthread_create,所以類似這種檢測會預設為多線程。

對於單線程的判斷使用_libc_single_threaded變數。

Sun RPC

去除對Sun RPC支援。

API

所有引用了Sun RPC相關的標頭檔的代碼,需要變更依賴。

  • 使用libtorpc-devel提供的rpc/rpc.h

  • 使用rpcsvc-proto-devel提供的rpcsvc/*.h

  • 使用rpcgen提供的rpcgen

GCC 10版本的重要變更及影響

下表列出了GCC 8GCC 10版本的重要變更,並介紹了這些變更所帶來的影響以及相應的解決方案。

類別

變更

相容性變更類型

影響

解決方案

-fno-common

GCC 10預設開啟-fno-common

API

common段允許程式定義多個同名的未經初始化的全域變數。

這些變數會在連結階段合并放入到bss段,而連結階段最多隻允許一個初始化同名變數存在。若啟用了-fno-common選項,在多個源檔案中定義了同名全域變數的程式在連結階段會失敗。

  • 保證至多隻有一個源檔案中定義了該全域變數,其他引用到的地方用extern關鍵字聲明該變數。

  • 開啟選項-fcommon保證向前相容的能力。

fortran

形參和實參不匹配時,GCC 10版本的fortran會識別為error

API

形參和實參不匹配時,編譯出現報錯。

  • 修改代碼保持形參和實參類型一致。

  • -fallow-argument-mismatch降級為warnings

C++ header

一些C++標準header不再包含<stdexcept><string>

API

應用程式編譯報錯。

根據報錯資訊,在程式中引入相關的標頭檔。

枚舉檢查

GCC 10對枚舉的檢查更為嚴格,枚舉元素不允許用於其他枚舉定義元素賦值。

API

應用程式編譯報錯。

正確使用枚舉。

LSE

GCC 10添加了-moutline-atomics,在-march=armv8-a選項中預設啟用。

API

該選項能夠在運行時檢測是aarch64機器否支援LSE指令,並且能夠將其應用於標準原子操作,從而提高原子的並發性。

正確使用該選項。GCC 10arm64更多指令集的支援,請參見AArch64 定義實現

GCC 10警示資訊變更說明

下表列出了GCC 8GCC 10版本相關的警示資訊變更。

說明

編譯警示並不會直接影響API的相容性。在應用程式遷移到Alibaba Cloud Linux 3系統時,如果出現編譯警示,建議修改應用程式代碼以規避這些警示資訊。

參數名

相容性變更類型

類型

說明

-Waddress-of-packed-member

API

新增

預設為enable

當結構體或者union中一個packed成員地址是未對齊指標時出現的編譯警告。

-Wzero-length-bounds

API

新增

-Warray-bounds啟用時,在訪問長度為0的數組元素時會觸發警告,這些元素可能會與同一對象的其他成員重疊。

-Warrary-bounds

API

增強

檢測更多的資料元素訪問越界和對長度為0的數組元素訪問。

-Wattribute-alios

API

增強

檢測它們之間的類型、別名、聲明與其目標之間的屬性是否匹配。

-Wformat-overflow

API

增強

編譯時間檢查使用格式化輸出函數是否有可能發生緩衝區溢位。預測到輸出將超過緩衝區界限時,編譯器就會發出警告。

-Wmissing-attributes

API

新增

檢測別名和弱引用聲明中的函數屬性是否丟失。

-Wformat-truncation

API

增強

-Wformat-overflow相輔相成。在使用像snprintf這樣的函數時,即使沒有發生溢出,但輸出被截斷的情況也會發出警告。

-Wstringop-overflow

API

增強

  • 檢測成員數組的更多邊界儲存包括零長度數組、動態分配的對象和可變長度數組,以及通過字串內建函數讀取未終止字元數組的更多執行個體。

  • 還可以通過調用新屬性訪問聲明的使用者定義函數來檢測越界訪問。

-Wreturn-local-addr

API

增強

檢測更多返回自動變數地址的情境。

-Wretrict

API

增強

檢測對動態指派至的重疊訪問。

-Warith-conversion

API

增強

-Warith-conversion選項重新啟用了disable-Wconversion-Wfloat-conversion-Wsign-conversion

相關文檔

瞭解更多版本變更資訊,請參考GlibcGCC的ReleaseNotes。