二進位制對應原始碼
有乙個程式
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 -ddynamic 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 載入過程中,系統分析動態庫的...