動態庫載入路徑之RPATH與RUNPATH 小記

2021-08-26 09:53:31 字數 3961 閱讀 7778

二進位制對應原始碼

有乙個程式

a.out

main.c

需要載入外掛程式a

liba.so

liba.c

a需要另乙個動態庫

libb.so

libb1.c 或 libb2.c

目錄結構:

/home/debao/ttt/a.out

/home/debao/ttt/liba.so

/home/debao/ttt/libb.so

/usr/lib/libb.so

#include #include typedef int (*funca)(int, int);

int main()

#include int funcb(int, int);

int funca(int a, int b)

#include int funcb(int a, int b)

#include int funcb(int a, int b)

$ gcc -shared -fpic libb2.c -o libb2.so

$ sudo mv libb2.so /usr/lib/libb.so

$ gcc -shared -fpic libb.c -o libb.so

$ gcc -shared -fpic liba.c -o liba.so -l. -lb

順便看看該elf檔案的頭部資訊:

$ readelf liba.so -d

dynamic section at offset 0xf20 contains 21 entries:

tag type name/value

0x00000001 (needed) shared library: [libb.so]

0x00000001 (needed) shared library: [libc.so.6]

...

恩,只有庫的檔名資訊,而沒有路徑資訊。

$ gcc main.c -ldl

$ ./a.out

hello from funca

hello from funcb 2

main: 12

程式:dlopen從當前目錄找到liba.so,然後卻在/usr/lib/中找到libb.so(沒有使用當前目錄的libb.so,這是我們需要的麼?)

$ gcc main.c -ldl  -wl,--rpath=.

$ ./a.out

hello from funca

hello from funcb 1

main: 12

恩,使用當前目錄的libb.so,很理想的東西

$ gcc main.c -ldl -wl,--rpath=.,--enable-new-dtags 

$ ./a.out

hello from funca

hello from funcb 2

main: 12

問題重新出現,使用的系統路徑中的libb.so 而不是當前目錄下的。

通過下列命令可以檢視:

$ readelf -d a.out

為了完整起見,列出前面3次編譯的程式的資訊:

dynamic section at offset 0xf20 contains 21 entries:

tag type name/value

0x00000001 (needed) shared library: [libdl.so.2]

0x00000001 (needed) shared library: [libc.so.6]

0x0000000c (init) 0x8048360

...

dynamic section at offset 0xf18 contains 22 entries:

tag type name/value

0x00000001 (needed) shared library: [libdl.so.2]

0x00000001 (needed) shared library: [libc.so.6]

0x0000000f (rpath) library rpath: [.]

0x0000000c (init) 0x8048360

....

dynamic section at offset 0xf10 contains 23 entries:

tag type name/value

0x00000001 (needed) shared library: [libdl.so.2]

0x00000001 (needed) shared library: [libc.so.6]

0x0000000f (rpath) library rpath: [.]

0x0000001d (runpath) library runpath: [.]

rpath and runpath給出這個問題的答案:

unless loading object has runpath:

rpath of the loading object,

then the rpath of its loader (unless it has a runpath), ...,

until the end of the chain, which is either the executable

or an object loaded by dlopen

unless executable has runpath:

rpath of the executable

ld_library_path

runpath of the loading object

ld.so.cache

default dirs

用它解釋第乙個程式:

環境變數ld_library_path,(沒有)

liba.so 的runpath (沒有)

ld.so.cache (沒有命中)

預設路徑/usr/lib (命中)

用它解釋第二個程式:

用它解釋第三個程式:

環境變數ld_library_path,(沒有)

liba.so 的runpath (沒有)

ld.so.cache (沒有命中)

預設路徑/usr/lib (命中)

有意思的就是這個程式了,可執行程式的runpath是乙個重要的判斷條件,卻並不被做為這兒搜尋路徑!!

本文是在kubuntu 11.10下編寫測試的。為了盡可能簡單,例子也都是認為製造的。而且我們看到,在使用rpath的時候是正常的,runpath一般來說,被推薦使用,但這兒它卻不能正常工作。

所以,當使用runpath時,我們需要明白:某些情況下可能需要設定環境變數 ld_library_path

動態庫載入路徑之RPATH與RUNPATH 小記

二進位制對應原始碼 有乙個程式 a.out main.c 需要載入外掛程式a liba.so liba.c a需要另乙個動態庫 libb.so libb1.c 或 libb2.c 目錄結構 home debao ttt a.out home debao ttt liba.so home debao ...

linux動態庫載入時搜尋路徑

對動態庫的實際應用還不太熟悉的讀者可能曾經遇到過類似 error while loading shared libraries 這樣的錯誤,這是典型的因為需要的動態庫不在動態鏈結器ld.so的搜尋路徑設定當中導致的。1 elf可執行檔案中動態段中dt rpath所指定的路徑。這實際上是通過一種不算很...

jni之動態庫的載入

一專案中,使用了多個動態庫,且動態庫之間存在依賴關係,假設為a.so及b.so,且b.so依賴於a.so。在使用static 進行動態庫載入的時候,始終提示b庫載入失敗,稱找不到依賴a,但是顯然第一部就載入了a,且載入成功。幾經周折發現,a的soname不為a,而是 a 載入過程中,系統分析動態庫的...