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

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


咨詢
建站咨詢
