libc.so.6小入門

轉自:網路

什麼是libc?

libc是C語言標準庫(C standard library)的縮寫,它是C語言程式開發中常用的庫之一。libc提供了一系列的函式和常量,用於處理字串、記憶體操作、輸入輸出、數學運算、日期時間等常見的程式設計任務。
C語言標準庫包含了一些核心的標頭檔案,如<stdio.h>、<stdlib.h>、<string.h>等,這些標頭檔案定義了許多常用的函式和型別。透過包含這些標頭檔案,開發者可以使用庫中提供的函式來完成各種任務,而無需從頭開始編寫相關的程式碼。
libc的實現會因不同的作業系統和編譯器而有所差異,但它們都遵循C語言標準,提供了一致的介面和功能。開發者可以在編寫C語言程式時直接呼叫這些庫函式,以提高開發效率並簡化程式碼編寫過程。

glibc、glib、libc之間的區別?

glibc、glib和libc是三個不同的庫,它們在不同的上下文中有不同的含義和作用。下面是它們之間的區別:
glibc(GNU C庫):glibc是GNU釋出的C語言標準庫,也被稱為GNU libc。它是Linux系統中最基礎的API之一,幾乎所有的執行庫都依賴於glibc。glibc不僅封裝了Linux作業系統提供的系統服務,還提供了許多其他必要功能的實現,如字串處理、記憶體管理、檔案操作、網路通訊、多執行緒支援等。glibc的實現遵循C語言標準,提供了一致的介面和功能,可以幫助開發者快速編寫高效、可靠的程式。在Linux系統中,glibc扮演著非常重要的角色,是Linux系統執行的基石之一。
glib:glib是一個通用的C語言工具庫,它是為了解決C語言中一些常見問題而設計的。glib提供了一些資料結構、執行緒支援、記憶體管理、字串處理、檔案操作等功能。它是一個跨平臺的庫,可以在不同的作業系統上使用。glib被廣泛應用於GNOME桌面環境和許多其他開源專案中。
libc(ANSI C標準庫):libc是C語言標準庫(C standard library)的縮寫,它是C語言程式開發中常用的庫之一。libc提供了一系列的函式和常量,用於處理字串、記憶體操作、輸入輸出、數學運算、日期時間等常見的程式設計任務。它是C語言程式的基礎庫,提供了許多常用的功能和介面。
總結來說,glibc是Linux系統中最底層的C語言標準庫,提供了豐富的系統服務和功能實現;glib是一個通用的C語言工具庫,提供了一些常見問題的解決方案;而libc是C語言標準庫,提供了基礎的函式和常量,用於處理常見的程式設計任務。

ANSI C和GNU C的區別

ANSI C和GNU C是兩種不同的C語言標準和實現,它們之間的區別如下:
ANSI C:ANSI C是C語言的標準化版本,由美國國家標準協會(ANSI)於1989年釋出。ANSI C標準規定了C語言的語法、語義和標準庫,使得不同的編譯器可以在不同的平臺上生成相同的程式碼。ANSI C標準化了C語言,使得C語言成為一種通用的程式語言,被廣泛應用於系統程式設計、嵌入式系統、網路程式設計等領域。
GNU C:GNU C是GNU專案釋出的C語言編譯器,也稱為gcc。GNU C是ANSI C的擴充套件版本,它提供了一些ANSI C沒有定義的語言特性和擴充套件庫。GNU C編譯器是一個跨平臺的編譯器,可以在不同的作業系統上使用,如Linux、Windows、Mac OS等。GNU C編譯器是開源的,可以自由使用和修改。
例如新增語法
1.零長度和變數長度陣列
2.case範圍
3.語句表示式
4.typeof關鍵字
5.可變引數宏
…還有很多,自己查
下面是一些示例程式碼來演示GNU C的擴充套件特性:
1. 零長度和變數長度陣列:
// 零長度陣列
structZeroLengthArray {
int

len;

int

data[

0

];

// 零長度陣列

};

// 變數長度陣列
voidvariableLengthArray(int size)

{

intarray

[size];

// 變數長度陣列

}

2. case範圍:
int

number =

5

;

switch

(number) {

case1

...

5

:

// 使用範圍匹配多個case標籤
printf

(

"Number is between 1 and 5\n"

);

break

;

case6

:

printf

(

"Number is 6\n"

);

break

;

default

:

printf

(

"Number is not in the range\n"

);

break

;

}

3. 語句表示式:
int

result = ({

int

a =

5

;

int

b =

10

;

a + b;

// 語句表示式,返回a + b的結果

});

printf

(

"Result: %d\n"

, result);

4. typeof關鍵字:

int

number

=

10

;

typeof

(

number

) newNumber;

// 使用typeof獲取number的型別

newNumber =

number

+

5

;

printf(

"New Number: %d\n"

, newNumber);

5. 可變引數宏:
#include<stdio.h>
#include<stdarg.h>
#define SUM(...) sum(__VA_ARGS__)
intsum(int count, ...)

{

va_list args;

va_start(args, count);

int

total =

0

;

for

(

int

i =

0

; i < count; i++) {

total += va_arg(args,

int

);

}

va_end(args);

return

total;

}

intmain()

{

int

result = SUM(

1

,

2

,

3

,

4

,

5

);

printf

(

"Sum: %d\n"

, result);

return0

;

}

這些示例程式碼展示了GNU C的擴充套件特性的用法。請注意,這些特性可能不被所有C編譯器支援,因此在使用時請確保目標平臺和編譯器的相容性。
libc.so.6的坑
接下來說一下我幾年前遇到的一個坑
在移植CentOS 7.9到RK3399上,並使用RK提供的updateEngine進行OTA升級時,遇到了一些問題。
首先,編譯生成的updateEngine工具在CentOS上無法執行,缺少libpng.so庫。為了解決這個問題,嘗試將libpng.so庫複製到系統中,但是發現libc.so等庫的版本太低。因此決定升級這些庫。
下載了glibc的原始碼,並按照以下步驟進行編譯:
1. 執行../configure
2. 執行make
3. 執行make install
如果出現錯誤,您透過搜尋解決了這些問題
升級完成後,updateEngine可以正常使用。然而,在釋出給測試進行測試,但是在過程中遇到了一些問題。例如,hwclock工具出現段錯誤,lspci工具重定向出錯,以及lspci -vvv | grep命令失敗並報錯。此外,執行yum update導致系統崩潰,解除安裝軟體時會意外解除安裝其他系統工具等。
然後發現舊版本的CentOS不存在這些問題,並且可以透過重新編譯hwclock和lspci等工具來解決。然而,由於yum update會導致系統不穩定,最後決定還原回去,問題得到解決。

反思方案

針對updateEngine的問題,有三種解決方案:
1.使用CentOS的庫來編譯updateEngine,只要它不依賴於較高版本的libc特性。可以修改Makefile來實現這一點。
2.進行靜態編譯,即將updateEngine可執行檔案所需的動態連結庫部分提取出來,連結到可執行檔案中,使其在執行時不依賴於動態連結庫。同樣,可以修改Makefile來實現靜態編譯。
3.修改配置檔案去除updateEngine的UI介面所需的libpng庫,因為並不需要它。

方案選擇

最後選擇了第三種方法
總結起來,CentOS之所以使用較舊的系統庫,是為了保證穩定性,伺服器OS首先centos。如果需要更新的話,可以考慮使用CentOS 8或更高版本,因為它們的系統庫已經比較新了。請記住,更新系統存在一定的風險,需要謹慎操作。
推薦閱讀點選標題可跳轉

相關文章