Linux ldd命令介绍
ldd(List Dynamic Dependencies)是一个*nix实用程序,它打印每个程序或共享库所需的共享对象(共享库)。它由Roland McGrath和Ulrich Drepper开发。如果某个程序缺少某个共享库,那么该程序将无法运行。
Linux ldd命令适用的Linux版本
ldd命令适用于大多数Linux发行版,但是在一些极其旧的a.out程序上不起作用,这些程序是在ldd支持被添加到编译器版本之前构建的²。如果你在这些程序上使用ldd,程序将尝试以argc = 0运行,结果将不可预测。
另外,要注意的是,在某些情况下(例如,当程序指定了一个非ld-linux.so的ELF解释器时),一些版本的ldd可能会尝试通过直接执行程序来获取依赖信息,这可能导致执行程序的ELF解释器中定义的任何代码,甚至执行程序本身²。因此,你永远不应该在不可信的可执行文件上使用ldd,因为这可能导致执行任意代码。一个更安全的替代方案是:
objdump -p /path/to/program | grep NEEDED
但是,这个替代方案只显示可执行文件的直接依赖,而ldd显示可执行文件的整个依赖树。
Linux ldd命令的基本语法
ldd命令的语法如下:
ldd [option]... file...
其中,option是可选的参数,file是要检查的程序或共享库的名称。
Linux ldd命令的常用选项或参数说明
ldd命令提供了一些有用的选项,下面是一些常用的:
选项 | 说明 |
---|---|
--version | 打印ldd的版本号 |
-v, --verbose | 打印所有信息,包括符号版本化数据等 |
-u, --unused | 打印未使用的直接依赖 |
-d, --data-relocs | 执行数据重定位并报告任何缺失的对象(仅适用于ELF) |
-r, --function-relocs | 执行数据对象和函数的重定位,并报告任何缺失的对象或函数(仅适用于ELF) |
--help | 打印使用信息 |
Linux ldd命令的实例
下面是一些ldd命令的实例,展示了它的用法和输出。
实例1:显示程序的共享库依赖
[linux@bashcommandnotfound.cn ~]$ ldd /bin/ls
linux-vdso.so.1 (0x00007ffd7f7e4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8f9c8c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8f9cc9a000)
这个实例显示了/bin/ls程序所需的共享库,以及它们被加载的地址。其中,linux-vdso和ld-linux是特殊的共享依赖,可以参考vdso (7)和ld.so (8)的文档²。
实例2:显示共享库的共享库依赖
[linux@bashcommandnotfound.cn ~]$ ldd /lib/x86_64-linux-gnu/libc.so.6
linux-vdso.so.1 (0x00007ffc9b7f9000)
ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f5a9f7a8000)
这个实例显示了/lib/x86_64-linux-gnu/libc.so.6共享库所需的共享库,以及它们被加载的地址。
实例3:显示程序的详细信息
[linux@bashcommandnotfound.cn ~]$ ldd -v /bin/ls
linux-vdso.so.1 (0x00007fffc8df4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a9f0c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a9f49a000)
Version information:
/bin/ls:
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6:
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
这个实例使用-v选项显示了/bin/ls程序的详细信息,包括符号版本化数据。
实例4:显示程序的未使用的直接依赖
[linux@bashcommandnotfound.cn ~]$ ldd -u /bin/ls
Unused direct dependencies:
/lib/x86_64-linux-gnu/libc.so.6
这个实例使用-u选项显示了/bin/ls程序的未使用的直接依赖。
实例5:执行程序的数据重定位并报告缺失的对象
[linux@bashcommandnotfound.cn ~]$ ldd -d /bin/ls
linux-vdso.so.1 (0x00007fffc8df4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a9f0c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a9f49a000)
这个实例使用-d选项执行了/bin/ls程序的数据重定位,并没有报告任何缺失的对象。如果有缺失的对象,ldd会在输出中显示“not found”。
实例6:执行程序的数据对象和函数的重定位并报告缺失的对象或函数
[linux@bashcommandnotfound.cn ~]$ ldd -r /bin/ls
linux-vdso.so.1 (0x00007fffc8df4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a9f0c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a9f49a000)
这个实例使用-r选项执行了/bin/ls程序的数据对象和函数的重定位,并没有报告任何缺失的对象或函数。如果有缺失的对象或函数,ldd会在输出中显示“undefined symbol”。
实例7:显示程序的快捷键
[linux@bashcommandnotfound.cn ~]$ ldd --help
Usage: ldd [OPTION]... FILE...
--help print this help and exit
--version print version information and exit
-d, --data-relocs process data relocations
-r, --function-relocs process data and function relocations
-u, --unused print unused direct dependencies
-v, --verbose print all information
这个实例使用--help选项显示了ldd命令的快捷键,以及它们的作用。
实例8:显示程序的版本信息
[linux@bashcommandnotfound.cn ~]$ ldd --version
ldd (GNU libc) 2.27
这个实例使用--version选项显示了ldd命令的版本信息。
实例9:显示一个不存在的程序的共享库依赖
[linux@bashcommandnotfound.cn ~]$ ldd /bin/foo
ldd: /bin/foo: No such file or directory
这个实例显示了当程序不存在时,ldd命令的输出。ldd会报告“No such file or directory”错误。
实例10:显示一个不是动态链接的程序的共享库依赖
[linux@bashcommandnotfound.cn ~]$ ldd /bin/ping
not a dynamic executable
这个实例显示了当程序不是动态链接的时,ldd命令的输出。ldd会报告“not a dynamic executable”错误。这意味着程序是静态链接的,不需要任何共享库。
评论区