新聞中心
在Linux系統(tǒng)中,ldd是一個(gè)非常實(shí)用的命令,它可以用來查看一個(gè)可執(zhí)行程序或動態(tài)鏈接庫所需要的依賴項(xiàng)。通過使用ldd命令,我們可以,了解它是如何工作的,以及在實(shí)際的開發(fā)中如何使用它。

成都創(chuàng)新互聯(lián)公司主要從事做網(wǎng)站、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)海城,10年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
一、ldd的基本用法
ldd命令的基本用法非常簡單,只需要在終端輸入ldd加上對應(yīng)的可執(zhí)行程序或動態(tài)鏈接庫文件路徑即可查看依賴項(xiàng)。例如,我們可以使用以下命令查看一個(gè)測試程序hello的依賴關(guān)系:
“`
ldd ./hello
“`
執(zhí)行結(jié)果會輸出hello程序所依賴的動態(tài)鏈接庫,例如:
“`
linux-vdso.so.1 => (0x00007fff541b7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21c45f1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21c49d2023)
“`
其中,linux-vdso.so.1是一個(gè)虛擬的共享庫,不會存在真正的文件中,而是在內(nèi)核中實(shí)現(xiàn)的。libc.so.6是C標(biāo)準(zhǔn)庫的動態(tài)鏈接庫,是任何Linux程序的基礎(chǔ)依賴項(xiàng)。/lib64/ld-linux-x86-64.so.2是默認(rèn)的動態(tài)鏈接器,也是一個(gè)必需的依賴項(xiàng),它負(fù)責(zé)在進(jìn)程啟動時(shí)將程序的依賴項(xiàng)加載到內(nèi)存中。
二、ldd的工作原理
在Linux中,程序和庫通常是以ELF格式存儲的,其中包含了程序的代碼、數(shù)據(jù)、符號和其他相關(guān)信息。而ldd命令則是通過解析這些ELF文件來查找依賴關(guān)系的。
在執(zhí)行l(wèi)dd命令后,它首先會讀取程序的ELF頭部信息,然后查找它所依賴的動態(tài)鏈接庫列表。每個(gè)動態(tài)鏈接庫都有一個(gè)DT_NEEDED結(jié)構(gòu),它包含了依賴庫的名字和路徑。ldd命令會根據(jù)這些信息來查找動態(tài)鏈接庫,并輸出到終端中。
除了查找動態(tài)鏈接庫,ldd命令還可以檢查可執(zhí)行文件中的符號表,以驗(yàn)證它們是否已正確地解析。如果符號表中存在未解析的符號,說明程序無法正常運(yùn)行,需要先解決這些依賴問題。
三、ldd在實(shí)際開發(fā)中的應(yīng)用
在實(shí)際開發(fā)中,ldd命令是一個(gè)非常有用的工具,可以幫助我們快速定位和解決依賴問題。以下是一些常見的用法:
1. 查找缺失的動態(tài)鏈接庫
如果程序無法正常運(yùn)行,或者在執(zhí)行時(shí)提示缺失某些庫文件,我們可以通過ldd命令來查找缺失的動態(tài)鏈接庫。例如:
“`
$ ldd ./hello
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21c45f1000)
libm.so.6 => not found
libgcc_s.so.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f21c43d4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21c49d2023)
“`
可以看到,上面的輸出結(jié)果中,程序缺失了libm.so.6和libgcc_s.so.1兩個(gè)庫文件。我們需要先安裝這些庫文件,才能正常運(yùn)行程序。
2. 檢查動態(tài)鏈接庫版本號
有時(shí)候,程序需要依賴的庫文件可能與當(dāng)前系統(tǒng)安裝的版本不匹配,這可能導(dǎo)致一些意想不到的問題。通過ldd命令,我們可以檢查動態(tài)鏈接庫的版本號,以確保它們與程序的要求相符。例如:
“`
$ ldd -v ./hello | grep libc.so.6
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f21c45f1000)
ld-linux-x86-64.so.2 (0xdeadbeef)
“`
通過這個(gè)命令,我們可以看到,程序要求的libc.so.6的版本號與當(dāng)前系統(tǒng)中安裝的版本完全一致,因此不會出現(xiàn)版本不匹配的問題。
3. 檢查符號表解析
當(dāng)程序中存在未解析的符號時(shí),會導(dǎo)致程序無法正常運(yùn)行。通過ldd命令,我們可以檢查程序的符號表,以驗(yàn)證它們是否已正確地解析。例如:
“`
$ ldd -r ./hello
linux-vdso.so.1 => (0x00007ffd3595e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5cd5b46000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5cd5ee7000)
“`
在這個(gè)例子中,我們使用了ldd的-r選項(xiàng)來檢查hello程序的符號表,如果符號表中存在 unresolved symbols,則會輸出對應(yīng)的錯誤信息。
綜上所述,ldd命令在Linux系統(tǒng)中是一個(gè)非常重要的工具,可以幫助我們快速定位和解決依賴問題,確保程序能夠正常運(yùn)行。通過,我們可以更好地理解它的工作原理,并在實(shí)際的開發(fā)中更好地運(yùn)用它。
相關(guān)問題拓展閱讀:
- Linux和FreeBSD在使用非系統(tǒng)自帶的gcc時(shí)的區(qū)別
Linux和FreeBSD在使用非系統(tǒng)自帶的gcc時(shí)的區(qū)別
下面拿CentOS 5和FreeBSD 9.0做下比較:
CentOS 5 自帶的gcc是gcc (GCC) 4.1.2,通過yum可以安裝gcc44 (GCC) 4.4.4
FreeBSD 9.0 自帶的gcc是gcc (GCC) 4.2.1,通過ports可以安裝gcc 4.6 (目前是4.6.2)
用C++寫一個(gè)非常簡單的C++程序:
int main(){
return 0;
}
然后用g++編譯:
# g++44 main.cpp -o main
然后用ldd查看,Linux下的輸出結(jié)果為:
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0xf000000)
libm.so.6 => /lib64/libm.so.6 (0xcc00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0xe400000)
libc.so.6 => /lib64/libc.so.6 (0xc400000)
/lib64/ld-linux-x86-64.so.2 (0xc000000)
FreeBSD下的輸出結(jié)果為:
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0×)
libm.so.5 => /lib/libm.so.5 (0x800b59000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800d7a000)
libc.so.7 => /lib/libc.so.7 (0x800f87000)
其中有兩行故意標(biāo)紅了。因?yàn)樗麄兪莵碜杂趃cc。那么就有這么一個(gè)問題:不同版本的gcc,這兩個(gè)庫,一樣嗎?或者我這么問,gcc 4.4、gcc 4.6、gcc 4.2、gcc 4.1相比,他們的C++標(biāo)準(zhǔn)庫(libstdc++.so)的接口一樣嗎? 實(shí)現(xiàn)一樣嗎?(此處指需要被編譯的那部分,如非模板類)
來看看CentOS怎么做的:
CentOS 5的gcc44-c++這個(gè)包,只帶了兩個(gè)so。/usr/lib/gcc/x86_64-redhat-linux6E/4.4.4/32/libstdc++.so和/usr/lib/gcc/x86_64-redhat-linux6E/4.4.4/libstdc++.so。而這兩個(gè)so竟然只是文本文件,內(nèi)容大概是這樣:
INPUT ( -lstdc++_nonshared /usr/lib64/libstdc++.so.6 )
也就是說,它會靜態(tài)鏈接到/usr/lib/gcc/x86_64-redhat-linux6E/4.4.4/libstdc++_nonshared.a這個(gè)文件,并動態(tài)鏈接到/usr/lib64/libstdc++.so.6(這個(gè)文件由gcc 4.1提供)
所以,在CentOS 5中,用gcc 4.4編譯出來的東西,運(yùn)行環(huán)境不需要安裝gcc 4.4 !
然后看FreeBSD怎么做的:
gcc 4.6的so,安裝在/usr/local/lib/gcc46/目錄下。如果是在64位環(huán)境下安裝的,那么只有64位版本的,沒有32位版本的。最關(guān)鍵的是,它確實(shí)是一個(gè)elf格式的so,而不是文本文件、軟鏈接什么的。
如果在FreeBSD下這么編譯一個(gè)文件:
# g++46 -o t test.cpp
那么它會錯誤的鏈接到4.2的so上
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0×)
libm.so.5 => /lib/libm.so.5 (0x800b59000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x800d7a000)
libc.so.7 => /lib/libc.so.7 (0x800f87000)
程序還能不能正常工作,那就看天命了。正確的做法是,在鏈接的時(shí)候加上-Wl,-rpath=/usr/local/lib/gcc46 。
現(xiàn)在如果只是為了讓ports用gcc 4.6,那么直接在/etc/make.conf中加入“USE_GCC=4.6”即可.
關(guān)于linux ldd的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都創(chuàng)新互聯(lián)建站主營:成都網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、網(wǎng)站改版的網(wǎng)站建設(shè)公司,提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、成都網(wǎng)站推廣、成都網(wǎng)站優(yōu)化seo、響應(yīng)式移動網(wǎng)站開發(fā)制作等網(wǎng)站服務(wù)。
文章標(biāo)題:深入探索Linux中的ldd機(jī)制(linuxldd)
文章路徑:http://m.fisionsoft.com.cn/article/dhdopdp.html


咨詢
建站咨詢
