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)
not found 表示缺失)ldd 不是二進位程式,而是 Shell Script:
$ file $(which ldd)
/usr/bin/ldd: Bourne-Again shell script, ASCII text executable
其核心機制是設定環境變數 LD_TRACE_LOADED_OBJECTS=1,讓動態連結器 ld-linux.so* 在載入程式時僅列印依賴而不執行程式。
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
動態連結器依序搜尋:
-Wl,-rpath),若有 DT_RUNPATH 則延後ldconfig 建立的快取)/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 |
LD_DEBUG=files /bin/ls 2>&1 | head -30
# 顯示搜尋路徑、開啟檔案、對應結果
readelf -d /path/to/binary | grep -E 'RPATH|RUNPATH'
# 或
chrpath -l /path/to/binary
ldd -v /path/to/binary | grep -A5 'libc.so.6'
# 顯示所需 GLIBC 版本
# 宿主機檢查容器二進位
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/libldd -r 掃描關鍵服務二進位,建立依賴基線LD_LIBRARY_PATH:系統庫路徑交給 ldconfig 管理,僅應用私有庫用環境變數LD_LIBRARY_PATH,防止提權攻擊精通 ldd 及其背後的動態連結機制,是解決 Linux 「庫依賴地獄」的核心鑰匙。
Ubuntu 安裝 Nox 編譯 make 報錯?升級 Boost 1.55 解決 1.42 版本過舊問題
Linux 執行程式提示 error while loading shared libraries 解決方案
Ubuntu 12.04 無法變更背景色?用 dconf-editor 手動修改 GTK 色彩方案
Linux 升級 OpenSSH 至 6.6p1 完整步驟:本地源配置、依賴安裝、備份舊配置、編譯安裝、服務重啟驗證、版本確認
CentOS 安裝 VNC 後報錯 "Could not start Xvnc" 解決方案