Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux ldd 指令完整解析:動態連結庫依賴檢查與除錯實戰

編輯:關於 Linux

ldd (List Dynamic Dependencies) 是 Linux 開發/運維必備工具,用於顯示可執行檔或共享庫的動態連結依賴關係。本文深入解析參數用法、運作原理、環境變數機制、搜尋順序與常見除錯場景。

基本用法與參數


ldd [選項]... 檔案...
選項長選項功能
--version顯示 ldd 版本
-v--verbose顯示完整資訊(含符號版本)
-d--data-relocs執行資料重定位測試,報告缺失物件 (ELF)
-r--function-relocs執行函數/物件重定位測試,報告缺失函數/物件 (ELF)
-u--unused顯示未使用的直接依賴
--help顯示說明

常用範例


# 基本依賴檢查
ldd /bin/bash

# 詳細模式(含版本資訊)
ldd -v /usr/bin/curl

# 檢查缺失依賴(除錯首選)
ldd -r /path/to/your/binary

# 檢查未使用的依賴(優化連結)
ldd -u /path/to/binary

輸出欄位解讀


$ ldd /bin/ls
linux-vdso.so.1 => (0x00007ffc12345000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f8a12345000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8a12345000)
libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f8a12345000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8a12345000)
  • 左側:依賴庫名稱 (SONAME)
  • =>:解析結果分隔符
  • 右側第一欄:實際載入路徑(not found 表示缺失)
  • 括號內:載入記憶體位址 (ASLR 隨機化)
  • linux-vdso.so.1:虛擬動態共享物件 (VDSO),核心提供的系統呼叫加速機制,非實體檔案
  • /lib64/ld-linux-x86-64.so.2:動態連結器本身

核心原理:環境變數觸發機制

ldd 不是二進位程式,而是 Shell Script:


$ file $(which ldd)
/usr/bin/ldd: Bourne-Again shell script, ASCII text executable

其核心機制是設定環境變數 LD_TRACE_LOADED_OBJECTS=1,讓動態連結器 ld-linux.so* 在載入程式時僅列印依賴而不執行程式。

手動模擬 ldd 行為


export LD_TRACE_LOADED_OBJECTS=1
/bin/ls
# 輸出即為 ldd /bin/ls 結果
unset LD_TRACE_LOADED_OBJECTS

關鍵環境變數完整表

環境變數對應 ldd 選項功能
LD_TRACE_LOADED_OBJECTS=1必要基礎啟用依賴追蹤模式
LD_WARN=yes-d資料重定位檢查
LD_BIND_NOW=yes-r立即綁定所有函數 (搭配 LD_WARN)
LD_DEBUG=unused-u顯示未使用依賴
LD_VERBOSE=1-v詳細輸出
LD_DEBUG=libs,files,symbols,bindings,versions除錯級別輸出 (極詳細)

直接呼叫動態連結器

繞過 ldd 腳本,直接使用 ld-linux.so*:


# 找出動態連結器路徑
ls -l /lib/ld-linux*.so*
# 或
readelf -l /bin/ls | grep interpreter

# 直接呼叫
/lib64/ld-linux-x86-64.so.2 --list /bin/ls
# 等同於 ldd /bin/ls

# 支援 --verify, --inhibit-cache 等進階選項
/lib64/ld-linux-x86-64.so.2 --verify /bin/ls

共享庫搜尋順序 (關鍵除錯知識)

動態連結器依序搜尋:

  1. DT_RPATH (編譯時嵌入,-Wl,-rpath),若有 DT_RUNPATH 則延後
  2. LD_LIBRARY_PATH 環境變數 (執行時指定,最高優先權但受限於安全機制)
  3. /etc/ld.so.cache (ldconfig 建立的快取)
  4. 預設路徑:/lib, /usr/lib (及架構專用如 /lib64, /lib/x86_64-linux-gnu)

特殊情況: 連結時加 -z nodeflib 會跳過步驟 3 和 4。

常見除錯場景與解決方案

現象原因分析解決方案
顯示 not found庫未安裝、路徑不在搜尋順序、架構不符 (x86 vs x64)安裝套件、設定 LD_LIBRARY_PATH、執行 ldconfig、檢查 file libxxx.so
版本衝突 (GLIBC_2.XX not found)編譯環境 GLIBC 版本 > 執行環境靜態連結、降級編譯環境、使用相容層、複製新版 GLIBC (風險高)
符號缺失 (undefined symbol)庫版本不符、缺少依賴庫、編譯遺漏nm -D libxxx.so | grep symbol 驗證、補裝正確版本
多版本共存衝突LD_LIBRARY_PATH 順序錯誤、RPATH 干擾調整路徑順序、使用 chrpath 修改 RPATH、容器隔離
權限被拒庫檔/目錄權限不足、SELinux 阻擋chmod 755 目錄、restorecon -R

進階除錯技巧

1. 追蹤實際載入過程


LD_DEBUG=files /bin/ls 2>&1 | head -30
# 顯示搜尋路徑、開啟檔案、對應結果

2. 檢查 RPATH/RUNPATH


readelf -d /path/to/binary | grep -E 'RPATH|RUNPATH'
# 或
chrpath -l /path/to/binary

3. 驗證符號版本


ldd -v /path/to/binary | grep -A5 'libc.so.6'
# 顯示所需 GLIBC 版本

4. 容器環境除錯


# 宿主機檢查容器二進位
ldd /var/lib/docker/overlay2/.../usr/bin/app
# 或進入容器
docker exec -it container ldd /usr/bin/app

最佳實踐建議

  • 編譯時:使用 -Wl,-rpath='$ORIGIN/../lib' 相對路徑,避免硬編碼絕對路徑
  • 部署時:將私有庫放在應用目錄 lib/,啟動腳本設定 LD_LIBRARY_PATH=$DIR/lib
  • 維運時:定期執行 ldd -r 掃描關鍵服務二進位,建立依賴基線
  • 避免濫用 LD_LIBRARY_PATH:系統庫路徑交給 ldconfig 管理,僅應用私有庫用環境變數
  • 安全:Setuid/setgid 程式會忽略 LD_LIBRARY_PATH,防止提權攻擊

精通 ldd 及其背後的動態連結機制,是解決 Linux 「庫依賴地獄」的核心鑰匙。

Copyright © Windows教程網 All Rights Reserved