ldd命令,查看依賴的動態庫信息 nm命令能夠列出一個函數庫文件中的符號表

ldd命令的做用是查看程序依賴的動態連接庫信息。使用nm命令也能夠獲取庫函數的信息;nm命令能夠列出一個函數庫文件中的符號表,它對靜態的庫函數和共享的庫函數都能起做用。 html

Linux動態庫的默認搜索路徑是/lib和/usr/lib。動態庫被建立後,通常都複製到這兩個目錄中。當程序執行時須要某動態庫,而且該動態庫還未加載到內存中,則系統會自動到這兩個默認搜索路徑中去查找相應的動態庫文件,而後加載該文件到內存中,這樣程序就可使用該動態庫中的函數,以及該動態庫的其它資源了。在Linux 中,動態庫的搜索路徑除了默認的搜索路徑外,還能夠經過如下三種方法來指定。
方法一:在配置文件/etc/ld.so.conf中指定動態庫搜索路徑
能夠經過編輯配置文件/etc/ld.so.conf來指定動態庫的搜索路徑,該文件中每行爲一個動態庫搜索路徑。每次編輯完該文件後,都必須運行命令ldconfig使修改後的配置生效。咱們經過例1來講明該方法。 node

方法二:經過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑
經過設定環境變量LD_LIBRARY_PATH也能夠指定動態庫搜索路徑。當經過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號":"分隔。下面經過例2來講明本方法。 linux


方法三:在編譯目標代碼時指定該程序的動態庫搜索路徑
在編譯目標代碼時指定程序的動態庫搜索路徑。這是經過gcc 的參數"-Wl,-rpath,"指定。當指定多個動態庫搜索路徑時,路徑之間用冒號":"分隔。 shell


當連接某個程序時,在運行期您能夠指定另外的搜索路徑。在 gcc 中,其 語法是 -Wl,-R/path。若是程序已經被連接,那麼您也能夠設置環境變量 LD_LIBRARY_PATH 來改變這一行爲。一般只是在應用程序須要搜索的路徑 不是系統級默認路徑的一部分時才須要這樣作,對大部分 Linux 系統來講,這種狀況不多見。 理論上,Mozilla 用戶能夠發佈某個使用這個路徑設置所編譯的二進制程序,可是他們 更傾向於發佈包裝器(wrapper)腳本,在啓動可執行程序以前正確地設置程序庫路徑。
設置程序庫路徑能夠爲兩個應用程序須要同一程序庫的不兼容版本的這種罕見狀況提供一個迂迴解決方案。可使用包裝器腳本使某一應用程序在使用特殊版本程序庫的目錄中進行搜索。這稱不上是一個 完美的解決方案,可是在某些狀況下,這是您能採用的最佳方法。
若是出於不得已的緣由須要爲不少程序添加某個路徑,那麼也能夠修改系統的默認搜索路徑。經過 /etc/ld.so.conf 控制動態連接器,該文件包含默認搜索路徑的列表。 對 LD_LIBRARY_PATH 中指定的任何路徑的搜索都要先於 ld.so.conf 中列出的路徑,因此用戶能夠覆蓋這些設置。
大部分用戶沒有理由修改系統默認程序庫搜索路徑;一般環境變量更適用於修改搜索路徑,好比 鏈接某個工具包中的程序庫,或者使用某個程序庫的較新版本的測試程序。

app

ldd的做用是打印可執行檔依賴的共享庫文件。它是glibc的一部分,由Roland McGrath和Ulrich Drepper維護:
$ ldd --version
ldd (GNU libc) 2.9
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.


可是ldd自己不是一個程序,而僅是一個shell腳本:
$ which ldd
/usr/bin/ldd
$ file /usr/bin/ldd 
/usr/bin/ldd: Bourne-Again shell script text executable


ldd命令實際上是依靠設置一些環境變量而實現的(也就是說ldd的做用只是設置一些環境變量的值)
如:LD_TRACE_LOADED_OBJECTS
只要設置其值非空便可。
$ export LD_TRACE_LOADED_OBJECTS=1
$ ls /usr
linux-gate.so.1 =>  (0xb7fac000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb7f93000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb7f79000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f70000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e0d000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7df4000)
/lib/ld-linux.so.2 (0xb7fad000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7df0000)
libattr.so.1 => /lib/libattr.so.1 (0xb7dea000)


撤銷該環境變量,ls即又能夠恢復正常使用:
$ unset LD_TRACE_LOADED_OBJECTS
$ ls  /usr/
bin  games  include  lib  lib32  lib64  local  sbin  share  src  X11R6


更多的環境變量:
一、LD_TRACE_LOADED_OBJECTS
二、LD_WARN
三、LD_BIND_NOW
四、LD_LIBRARY_VERSION
五、LD_VERBOSE
六、LD_DEBUG


ldd默認開啓的環境變量是:LD_TRACE_LOADED_OBJECTS=1
其餘的變量(和值)分別對應一些選項:
-d, --data-relocs -> LD_WARN=yes
-r, --function-relocs ->LD_WARN和LD_BIND_NOW=yes
-u, --unused -> LD_DEBUG="unused"
-v, --verbose -> LD_VERBOSE=yes
LD_TRACE_LOADED_OBJECTS爲必要環境變量,其餘視具體狀況。


更爲詳細的命令選項(或者參看man、info):
$ ldd --help
Usage: ldd [OPTION]... FILE...
--help              print this help and exit
--version           print version information and exit
-d, --data-relocs       process data relocations
-r, --function-relocs   process data and function relocations
-u, --unused            print unused direct dependencies
-v, --verbose           print all information
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.


可是ldd命令的本質是執行了:/lib/ld-linux.so.* 
咱們能夠從以上的內容中(ls /usr中)發現:/lib/ld-linux.so.2 (0xb7fad000)。
$ ls -l /lib/ld-linux.so.* 
lrwxrwxrwx 1 root root 9 2009-09-05 22:54 /lib/ld-linux.so.2 -> ld-2.9.so
剛編譯後的文件多是:/lib/ld.so。若是是libc5則是/lib/ld-linux.so.1, 而glibc2應該是/lib/ld-linux.so.2。


$ /lib/ld-linux.so.2  --list /bin/ls
linux-gate.so.1 =>  (0xb8050000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0xb8037000)
libselinux.so.1 => /lib/libselinux.so.1 (0xb801d000)
libacl.so.1 => /lib/libacl.so.1 (0xb8014000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eb1000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7e98000)
/lib/ld-linux.so.2 (0xb8051000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7e94000)
libattr.so.1 => /lib/libattr.so.1 (0xb7e8e000)
咱們能夠看到以上等同於ldd ls。/lib/ld-linux.so.2還有其餘一些選項:
一、--verify 
二、--library-path PATH
三、--inhibit-rpath LIST


ldd能夠得到的共享庫文件,實際上是經過讀取ldconfig命令組建起來的文件(/etc/ld.so.cache)。
默認的共享庫文件搜索/lib優先於/usr/lib,並且也只有這個2個目錄。若是想要加入其餘路徑,則須要經過ldconfig命令配置相關文件。
通常ld-linux.so會按照如下順序搜索共享庫:
一、DT_RPATH或DT_RUNPATH段
二、環境變量LD_LIBRARY_PATH
三、/etc/ld.so.cache文件中的路徑,但若是可執行程序在鏈接時候添加了-z nodeflib選項,則跳過。
四、默認路徑/lib和/usr/lib,但若是添加了-z nodeflib,則跳過。


還有一些額外的環境變量能夠參看man ld.so。


更爲詳細的內容:
一、man ldd(http://www.kernel.org/doc/man-pages/online/pages/man1/ldd.1.html)
二、man ldconfig(http://www.kernel.org/doc/man-pages/online/pages/man8/ldconfig.8.html)
三、man ld.so(http://www.kernel.org/doc/man-pages/online/pages/man8/ld.so.8.html)


能夠參見的文章:
一、Linux 動態庫剖析(http://www.ibm.com/developerworks/cn/linux/l-dynamic-libraries/)
二、剖析共享程序庫http://www.ibm.com/developerworks/cn/linux/l-shlibs.html)
三、ldd命令的原理與使用方法(http://hi.baidu.com/wstone_h/blog/item/af67700a80a01e1594ca6b29.html) 函數

相關文章
相關標籤/搜索