ldd只能分析elf文件的静态依赖,不读取进程内存,故无法查看运行中进程实际加载的共享库;pldd则通过/proc/pid/maps动态提取已映射的.so路径,专用于运行时库检测。

ldd 不能查运行中进程的共享库,它只分析静态依赖;真正要查进程正在用哪些共享库,得用 pldd。
为什么 ldd 对运行中的进程无效
ldd 本质是模拟动态链接器(ld-linux.so)加载目标文件的过程,但它不启动进程,也不读取内存状态。它只解析 ELF 文件头和 .dynamic 段里的 NEEDED 条目,属于静态分析工具。
这意味着:
- 对未运行的可执行文件或 .so 文件有效,比如
ldd ./myapp - 对已运行的进程 PID 完全无效——
ldd 1234不会报错但输出的是“not a dynamic executable”,因为 1234 是数字不是 ELF 文件 - 无法反映
dlopen()动态加载的库、LD_PRELOAD注入的库、或运行时通过memfd_create加载的匿名库
pldd 是专为运行中进程设计的工具
pldd 由 glibc 提供,直接读取目标进程的 /proc/PID/maps 和 /proc/PID/smaps,提取所有被映射为 r-xp(可执行)且路径以 .so 结尾的内存段,再过滤掉内核 VDSO、vdso、vvar 等伪对象。
使用方式很简单:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
-
pldd 1234—— 查看 PID 为 1234 的进程当前加载的所有共享库 -
pldd $(pidof nginx)—— 查看 nginx 主进程的动态库列表
注意:pldd 需要具备 ptrace 权限,普通用户对非子进程通常无权调用,会报 Operation not permitted。解决方法是:
- 用 root 执行
- 或给
pldd设置cap_sys_ptrace+ep能力(不推荐在生产环境随意开放) - 或改用
cat /proc/1234/maps | grep '\.so' | awk '{print $6}' | sort -u作为轻量替代(但会漏掉无路径的 memfd 库)
ldd -r 和 pldd 解决的是完全不同的问题
ldd -r 的作用是检查可执行文件或共享库在加载时是否能成功完成符号重定位,即是否存在未定义的函数或全局变量引用。它不关心进程是否在跑,只做链接期验证。
常见误用场景:
- 看到程序启动失败报
undefined symbol: foo_bar,第一反应是pldd—— 错,该用ldd -r ./myapp查静态符号缺失 - 怀疑某进程偷偷加载了自定义 hook 库,想确认它到底用了哪些 .so —— 该用
pldd,ldd完全看不到运行时行为
二者不可互相替代:一个管“编译链接时能不能连上”,一个管“运行时实际映射了哪些”。
容易忽略的关键细节
即使你正确用了 pldd,以下几点仍常被跳过:
-
pldd不显示版本号或 SONAME,只列绝对路径。若需确认具体版本,得手动readelf -d /path/to/lib.so | grep SONAME - 容器内进程的
pldd输出路径可能指向容器挂载前的宿主机路径(如/lib/x86_64-linux-gnu/libc.so.6),不代表容器镜像里真有这个文件 -
ldd对 setuid 程序默认禁用(出于安全),而pldd在 ptrace 可用前提下不受此限,但需注意权限隔离边界










