www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件

對(duì)動(dòng)態(tài)庫的實(shí)際應(yīng)用還不太熟悉的讀者可能曾經(jīng)遇到過類似“error while loading shared libraries”這樣的錯(cuò)誤,這是典型的因?yàn)樾枰膭?dòng)態(tài)庫不在動(dòng)態(tài)鏈接器ld.so的搜索路徑設(shè)置當(dāng)中導(dǎo)致的。

具體說來,動(dòng)態(tài)鏈接器ld.so按照下面的順序來搜索需要的動(dòng)態(tài)共享庫:

1.ELF可執(zhí)行文件中動(dòng)態(tài)段中DT_RPATH所指定的路徑。這實(shí)際上是通過一種不算很常用,卻比較實(shí)用的方法所設(shè)置的:編譯目標(biāo)代碼時(shí),可以對(duì)gcc加入鏈接參數(shù)“-Wl,-rpath”指定動(dòng)態(tài)庫搜索路徑;

2.環(huán)境變量LD_LIBRARY_PATH指定的動(dòng)態(tài)庫搜索路徑;

3./etc/ld.so.cache中所緩存的動(dòng)態(tài)庫路徑(如果支持ld.so.cache的話)。這可以通過修改配置文件/etc/ld.so.conf中指定的動(dòng)態(tài)庫搜索路徑來改變;

4.默認(rèn)的動(dòng)態(tài)庫搜索路徑/lib;

5.默認(rèn)的動(dòng)態(tài)庫搜索路徑/usr/lib。

在嵌入式Linux系統(tǒng)的實(shí)際應(yīng)用中,1和2被經(jīng)常使用,也有一些相對(duì)簡單的的嵌入式系統(tǒng)會(huì)采用4或5的路徑來規(guī)范動(dòng)態(tài)庫。3在嵌入式系統(tǒng)中使用的比較少,因?yàn)橛泻芏嘞到y(tǒng)根本就不支持ld.so.cache。

4和5的方式非常簡單,只要將所需要的庫放到/lib或/usr/lib就可以解決找不到庫的問題,不過對(duì)于大一些的系統(tǒng)來說,不太方便管理。1和2的方式要稍微復(fù)雜一些,下面我們用一個(gè)非常簡單的例子來說明如何應(yīng)用。

首先編寫一個(gè)最簡單的動(dòng)態(tài)共享庫,源代碼pirnt.c如下:

1 #include <STdio.h>

2

3 void print_foo()

4 {

5 printf("fooooooooo\n");

6 }

注意將它編譯成共享庫:

# gcc print.c -shared -o libprint.so

# file libprint.so

libprint.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped

調(diào)用該共享庫main.c代碼如下:

1 #include <stdio.h>

2

3 extern void print_foo();

4

5 int main()

6 {

7 print_foo();

8

9 return 0;

10 }

編譯之后的運(yùn)行結(jié)果如下:

# gcc main.c -L./ -lprint -o pfoo

# ./pfoo

./pfoo: error while loading shared libraries: libprint.so: cannot open shared object file: No such file or directory

這便是典型的找不到動(dòng)態(tài)庫的錯(cuò)誤。通常我們可以通過設(shè)置環(huán)境變量LD_LIBRARY_PATH來指定動(dòng)態(tài)庫的搜索路徑(即上面的方法2),比如這樣就可以正確運(yùn)行了:

# export LD_LIBRARY_PATH=./

# ./pfoo

fooooooooo

但這種方法有一個(gè)明顯的缺點(diǎn):一旦LD_LIBRARY_PATH被設(shè)定,則在這個(gè)環(huán)境變量生效的范圍之內(nèi),所有其他的ELF可執(zhí)行程序也會(huì)按照這個(gè)順序去搜索動(dòng)態(tài)庫,這樣勢(shì)必會(huì)造成搜索時(shí)的一些浪費(fèi)。

我們也可以使用另外一種方案來解決這種問題,即利用參數(shù)“-Wl,-rpath”在編譯時(shí)指定運(yùn)行時(shí)的搜索路徑(即上面的方法1),如下所示:

# unset LD_LIBRARY_PATH

# echo $LD_LIBRARY_PATH

# gcc main.c -L./ -lprint -o pfoo_r -Wl,-rpath=./

# ./pfoo

./pfoo: error while loading shared libraries: libprint.so: cannot open shared object file: No such file or directory

# ./pfoo_r

fooooooooo

我們首先unset了LD_LIBRARY_PATH,可以看到它已經(jīng)不再有效了(當(dāng)然這不是使用參數(shù)“-Wl,-rpath”的必要步驟,在這里只是為了說明它已經(jīng)不再起作用了),而且”pfoo”程序運(yùn)行時(shí)也會(huì)發(fā)生找不到庫的錯(cuò)誤,而我們加入編譯參數(shù)“-Wl,-rpath,./”之后得到的pfoo_r程序則能正常運(yùn)行。

事實(shí)上我們可以通過readelf工具來查看兩個(gè)文件的差異:

# readelf -d pfoo

Dynamic segment at offset 0x514 contains 21 entries:

Tag Type Name/Value

0x00000001 (NEEDED) Shared library: [libprint.so]

0x00000001 (NEEDED) Shared library: [libc.so.6]

0x0000000c (INIT) 0x8048344

0x0000000d (FINI) 0x80484e0

0x00000004 (HASH) 0x8048128

0x00000005 (STRTAB) 0x8048240

0x00000006 (SYMTAB) 0x8048170

0x0000000a (STRSZ) 178 (bytes)

0x0000000b (SYMENT) 16 (bytes)

0x00000015 (DEBUG) 0x0

0x00000003 (PLTGOT) 0x80495f8

0x00000002 (PLTRELSZ) 16 (bytes)

0x00000014 (PLTREL) REL

0x00000017 (JMPREL) 0x8048334

0x00000011 (REL) 0x804832c

0x00000012 (RELSZ) 8 (bytes)

0x00000013 (RELENT) 8 (bytes)

0x6ffffffe (VERNEED) 0x804830c

0x6fffffff (VERNEEDNUM) 1

0x6ffffff0 (VERSYM) 0x80482f2

0x00000000 (NULL) 0x0

[root@localhost ldpath]# readelf -d pfoo_r

Dynamic segment at offset 0x518 contains 22 entries:

Tag Type Name/Value

0x00000001 (NEEDED) Shared library: [libprint.so]

0x00000001 (NEEDED) Shared library: [libc.so.6]

0x0000000f (RPATH) Library rpath: [./]

0x0000000c (INIT) 0x8048348

0x0000000d (FINI) 0x80484e4

0x00000004 (HASH) 0x8048128

0x00000005 (STRTAB) 0x8048240

0x00000006 (SYMTAB) 0x8048170

0x0000000a (STRSZ) 181 (bytes)

0x0000000b (SYMENT) 16 (bytes)

0x00000015 (DEBUG) 0x0

0x00000003 (PLTGOT) 0x8049*

0x00000002 (PLTRELSZ) 16 (bytes)

0x00000014 (PLTREL) REL

0x00000017 (JMPREL) 0x8048338

0x00000011 (REL) 0x8048330

0x00000012 (RELSZ) 8 (bytes)

0x00000013 (RELENT) 8 (bytes)

0x6ffffffe (VERNEED) 0x8048310

0x6fffffff (VERNEEDNUM) 1

0x6ffffff0 (VERSYM) 0x80482f6

0x00000000 (NULL) 0x0

“readelf -d”可以用來查看ELF文件的動(dòng)態(tài)節(jié)(Dynamic Section)。對(duì)比pfoo 和pfoo_r的結(jié)果我們可以發(fā)現(xiàn),pfoo_r中多出來了RPATH項(xiàng),指定”Library rpath: [./]”。通過這種方式,我們可以用非常小的代價(jià)(僅增加幾乎可以忽略的空間開銷),對(duì)每個(gè)ELF文件都指定最優(yōu)化的搜索路徑,達(dá)到提升性能的目的。這是我們比較推薦的一種方法。當(dāng)然了,具體如果操作依賴于具體的軟件系統(tǒng)的情況,簡單的系統(tǒng)中直接將所有的庫都放到/lib下也未嘗不是一種簡單易行的優(yōu)化方案。



miaomi

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

CPU親和度通過限制進(jìn)程或線程可以運(yùn)行的CPU核心集合,使得它們只能在指定的CPU核心上執(zhí)行。這可以減少CPU緩存的失效次數(shù),提高緩存命中率,從而提升系統(tǒng)性能。

關(guān)鍵字: Linux 嵌入式

在Linux系統(tǒng)性能優(yōu)化中,內(nèi)存管理與網(wǎng)絡(luò)連接處理是兩大核心領(lǐng)域。vm.swappiness與net.core.somaxconn作為關(guān)鍵內(nèi)核參數(shù),直接影響系統(tǒng)在高負(fù)載場(chǎng)景下的穩(wěn)定性與響應(yīng)速度。本文通過實(shí)戰(zhàn)案例解析這兩個(gè)...

關(guān)鍵字: Linux 內(nèi)存管理

對(duì)于LLM,我使用b谷歌Gemini的免費(fèi)層,所以唯一的成本是n8n托管。在使用了n8n Cloud的免費(fèi)積分后,我決定將其托管在Railway上(5美元/月)。然而,由于n8n是開源的,您可以在自己的服務(wù)器上托管它,而...

關(guān)鍵字: 人工智能 n8n Linux

在Linux系統(tǒng)管理中,權(quán)限控制是安全運(yùn)維的核心。本文通過解析/etc/sudoers文件配置與組策略的深度應(yīng)用,結(jié)合某金融企業(yè)生產(chǎn)環(huán)境案例(成功攔截98.7%的非法提權(quán)嘗試),揭示精細(xì)化權(quán)限管理的關(guān)鍵技術(shù)點(diǎn),包括命令別...

關(guān)鍵字: Linux 用戶權(quán)限 sudoers文件

Linux內(nèi)核中的信號(hào)量(Semaphore)是一種用于資源管理的同步原語,它允許多個(gè)進(jìn)程或線程對(duì)共享資源進(jìn)行訪問控制。信號(hào)量的主要作用是限制對(duì)共享資源的并發(fā)訪問數(shù)量,從而防止系統(tǒng)過載和數(shù)據(jù)不一致的問題。

關(guān)鍵字: Linux 嵌入式

在云計(jì)算與容器化技術(shù)蓬勃發(fā)展的今天,Linux網(wǎng)絡(luò)命名空間(Network Namespace)已成為構(gòu)建輕量級(jí)虛擬網(wǎng)絡(luò)的核心組件。某頭部互聯(lián)網(wǎng)企業(yè)通過命名空間技術(shù)將測(cè)試環(huán)境資源消耗降低75%,故障隔離效率提升90%。本...

關(guān)鍵字: Linux 云計(jì)算

在Linux內(nèi)核4.18+和主流發(fā)行版(RHEL 8/Ubuntu 20.04+)全面轉(zhuǎn)向nftables的背景下,某電商平臺(tái)通過遷移將防火墻規(guī)則處理效率提升40%,延遲降低65%。本文基于真實(shí)生產(chǎn)環(huán)境案例,詳解從ipt...

關(guān)鍵字: nftables Linux

在Linux設(shè)備驅(qū)動(dòng)開發(fā)中,等待隊(duì)列(Wait Queue)是實(shí)現(xiàn)進(jìn)程睡眠與喚醒的核心機(jī)制,它允許進(jìn)程在資源不可用時(shí)主動(dòng)放棄CPU,進(jìn)入可中斷睡眠狀態(tài),待資源就緒后再被喚醒。本文通過C語言模型解析等待隊(duì)列的實(shí)現(xiàn)原理,結(jié)合...

關(guān)鍵字: 驅(qū)動(dòng)開發(fā) C語言 Linux

在Unix/Linux進(jìn)程間通信中,管道(pipe)因其簡單高效被廣泛使用,但默認(rèn)的半雙工特性和無同步機(jī)制容易導(dǎo)致數(shù)據(jù)競爭。本文通過父子進(jìn)程雙向通信案例,深入分析互斥鎖與狀態(tài)機(jī)在管道同步中的應(yīng)用,實(shí)現(xiàn)100%可靠的數(shù)據(jù)傳...

關(guān)鍵字: 管道通信 父子進(jìn)程 Linux

RTOS :RTOS的核心優(yōu)勢(shì)在于其實(shí)時(shí)性。它采用搶占式調(diào)度策略,確保高優(yōu)先級(jí)任務(wù)能夠立即獲得CPU資源,從而在最短時(shí)間內(nèi)完成處理。RTOS的實(shí)時(shí)性是通過嚴(yán)格的時(shí)間管理和任務(wù)調(diào)度算法實(shí)現(xiàn)的,能夠滿足對(duì)時(shí)間敏感性要求極高的...

關(guān)鍵字: Linux RTOS
關(guān)閉