ldd 命令详解
更新时间:2026-09-17。「一个命令一个文档」系列,属于开发构建与二进制族。程序在一台机器能跑、另一台报缺
.so,最先用 ldd 看它到底依赖哪些共享库、每条解析到了哪里。
一、基本用法
bash
ldd /usr/bin/nginx # 列出该 ELF 的直接/间接共享依赖与路径
ldd ./a.out
ldd -v ./a.out # 显示版本符号需求(GLIBC_2.xx)
ldd -u ./a.out # 显示未使用的直接依赖
ldd -r ./a.out # 重定位数据/函数并报告缺失符号输出形如:
bash
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f..)
/lib64/ld-linux-x86-64.so.2 # 动态链接器本身
libfoo.so => not found # 缺库:路径没进缓存/没安装=> not found 就是缺库或搜索路径问题,配合 ldconfig/LD_LIBRARY_PATH 解决。
二、常见排障
- 部署到旧系统报
version 'GLIBC_2.34' not found:ldd -v/objdump -T看二进制要求的 glibc 符号版本高于目标机 glibc;glibc 不能简单替换,应在更老的基线系统/容器里构建,或静态处理部分依赖。 not found:库没装、SONAME 版本不对、或目录没ldconfig;用ldconfig -p | grep libfoo确认缓存。- 同名库被劫持到错误路径:检查
LD_LIBRARY_PATH、RPATH(readelf -d看 RUNPATH),排查误用了非预期目录的库。
三、安全警告与更安全的替代
ldd 并不是单纯"读文件":在 glibc 实现里,它通过设置 LD_TRACE_LOADED_OBJECTS 等环境变量间接加载执行该程序来打印依赖。因此对来源不可信的二进制直接 ldd 有执行其代码的理论风险:
bash
# 只读、不执行目标的替代方式
objdump -p ./a.out | grep NEEDED
readelf -d ./a.out | grep NEEDED
LD_TRACE_LOADED_OBJECTS=1 ./a.out # 等价跟踪,但同样会经过加载器排查"需要哪些库"用 readelf -d(只看 ELF 头里的 NEEDED)最安全;想看实际解析到的路径才用 ldd。
四、静态链接与跨平台
- 全静态链接(
-static)的二进制 ldd 输出not a dynamic executable,无外部.so。 - ldd 只能解析本机架构、本机加载器能识别的 ELF;交叉编译的 ARM 二进制在 x86 上路径无法正常解析,用对应工具链的
readelf。 - Windows DLL 依赖不归 ldd 管(用
objdump -p/windeployqt 等)。
相关命令
刷新库缓存用 ldconfig,看 ELF 段/符号用 readelf/objdump(见 ELF 概念与 C 专家篇编译链接),运行时报错排查配合
strace -f -e openat。
总结
ldd 二进制 列出其运行时共享库依赖及解析路径:=> not found 直指缺库或 ldconfig/路径问题,-v 看 GLIBC 符号版本(治"高版本编译低版本跑不起来");但 glibc 的 ldd 会经加载器间接执行目标,不要对不可信二进制使用,只读 NEEDED 用 readelf -d/objdump -p 更安全,全静态程序则显示 not a dynamic executable。