注:本文为 “Linux | 程序 / 进程调用库依赖” 相关文章合辑。
英文引文,机翻未校。
未整理去重。
How to Check Library Dependencies in Linux
如何在 Linux 系统中检查库依赖关系
Mohd Shakir Zakaria
Programs on Linux often require external libraries to run correctly. These libraries are either loaded dynamically during runtime or built directly into the program. By using shared libraries, programs can reduce size and reuse common code. Typically, shared libraries are stored in the /lib or /usr/lib directories.
在 Linux 系统上的程序常常需要外部库才能正确运行。这些库要么在运行时动态加载,要么直接构建到程序中。通过使用共享库,程序可以减小体积并复用通用代码。通常,共享库存储在 /lib 或 /usr/lib 目录中。
A program compiled on one version of Linux may not work on another if the required libraries are missing or incompatible. This can lead to errors, especially when the program tries to load a shared library that is absent. Missing libraries or incorrect versions can prevent the program from starting, often resulting in an error like cannot open shared object file.
在一个版本的 Linux 上编译的程序,如果在另一个版本的系统中缺少所需的库或者库不兼容,可能无法正常运行。这可能会导致错误,尤其是当程序尝试加载一个不存在的共享库时。缺少库或者使用了不正确的库版本可能会阻止程序启动,常常会导致类似 “无法打开共享对象文件” 这样的错误。
$ sudo dpkg
sudo: error while loading shared libraries: libpthread.so.0:
cannot open shared object file: No such file or directory
To fix these issues, you can inspect the program’s shared library dependencies. Linux provides tools like ldd to list dynamic libraries required by a program. These tools help identify the exact dependencies so that missing libraries can be installed or updated as needed.
为了解决这些问题,你可以检查程序的共享库依赖关系。Linux 提供了诸如 ldd 这样的工具来列出一个程序所需的动态库。这些工具有助于确定确切的依赖关系,以便根据需要安装或更新缺失的库。
Steps to Check Library Dependencies in Linux
在 Linux 系统中检查库依赖关系的步骤
1. Open the terminal application.
打开终端应用程序。
2. Determine the absolute path of the program you want to inspect.
确定你想要检查的程序的绝对路径。
$ which bash
/usr/bin/bash
3. ldd
Display the shared object dependencies of the program.
显示该程序的共享对象依赖关系。
$ ldd /usr/bin/bash
linux-vdso.so.1 (0x00007ffdd2749000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fcecb9b6100)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcecb9b0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcecb7c5000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcecbb21000)
The ldd command shows all shared libraries required by a program. The path returned points to where each library is located on the system.
ldd 命令会显示一个程序所需的所有共享库。返回的路径指向系统中每个库所在的位置。
4. ldd --verbose
Run ldd
in verbose mode to view additional information.
以详细模式运行 ldd 命令以查看更多信息。
$ ldd --verbose /usr/bin/bash
linux-vdso.so.1 (0x00007ffce299c000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f6fb24dd000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6fb24d6100)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6fb22ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6fb2648000)
Version information:
/usr/bin/bash:
libdl.so.2 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libdl.so.2
libtinfo.so.6 (NCURSES6_TINFO_5.0.19991023) => /lib/x86_64-linux-gnu/libtinfo.so.6
libc.so.6 (GLIBC_2.11) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.8) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.15) => /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.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/libtinfo.so.6:
libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6
libc.so.6 (GLIBC_2.16) => /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.4) => /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/libdl.so.2:
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
libc.so.6 (GLIBC_PRIVATE) => /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.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
More options for ldd:
ldd 命令的更多选项:
$ 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
5. readelf
Use readelf
to check dynamic library dependencies of a program.
使用 readelf 命令检查一个程序的动态库依赖关系。
$ readelf --dynamic /usr/bin/bash | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libtinfo.so.6]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
6. proc
Inspect libraries required by a running process using the proc
filesystem.
使用 proc 文件系统检查正在运行的进程所需的库。
$ awk '/\.so/{print $6}' /proc/$(pgrep bash | head -n1)/maps | sort -u
/usr/lib/x86_64-linux-gnu/ld-2.29.so
/usr/lib/x86_64-linux-gnu/libc-2.29.so
/usr/lib/x86_64-linux-gnu/libdl-2.29.so
/usr/lib/x86_64-linux-gnu/libnss_files-2.29.so
/usr/lib/x86_64-linux-gnu/libtinfo.so.6.1
7. lsof
List memory-mapped shared libraries of a running process using lsof
.
使用 lsof 命令列出正在运行的进程的内存映射共享库。
$ lsof -p $(pgrep bash | head -n1) | grep mem
bash 4470 user mem REG 8,1 51672 404577 /usr/lib/x86_64-linux-gnu/libnss_files-2.29.so
bash 4470 user mem REG 8,1 14529344 401393 /usr/lib/locale/locale-archive
bash 4470 user mem REG 8,1 2000480 403822 /usr/lib/x86_64-linux-gnu/libc-2.29.so
bash 4470 user mem REG 8,1 18656 403961 /usr/lib/x86_64-linux-gnu/libdl-2.29.so
bash 4470 user mem REG 8,1 183528 404929 /usr/lib/x86_64-linux-gnu/libtinfo.so.6.1
bash 4470 user mem REG 8,1 26402 789841 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
bash 4470 user mem REG 8,1 179032 403610 /usr/lib/x86_64-linux-gnu/ld-2.29.so
pgrep bash | head -n1 fetches the process ID of the first bash process running.
pgrep bash | head -n1 会获取正在运行的第一个 bash 进程的进程 ID。
8. pmap
Use pmap
to check the memory maps of a running process and list shared libraries.
使用 pmap 命令检查正在运行的进程的内存映射并列出共享库。.
$ pmap $(pgrep bash | head -n1) | grep \.so | awk '{ print $4 }' | sort -u
ld-2.29.so
libc-2.29.so
libdl-2.29.so
libnss_files-2.29.so
libtinfo.so.6.1
查看 Linux 上程序或进程用到的库
| 2014-08-14 11:00
问题:当调用一个特定的可执行文件在运行时载入了哪些共享库。是否有方法可以明确 Linux 上可执行程序或运行进程的共享库依赖关系?
1. ldd
查看可执行程序的共享库依赖关系
ldd 命令
调用动态链接器去找到程序的库文件依赖关系,找出某个特定可执行依赖的库.
$ ldd /path/to/program
注意!并不推荐为任何不可信的第三方可执行程序运行 ldd,因为某些版本的 ldd 可能会直接调用可执行程序来明确其库文件依赖关系,这样可能不安全。
objdump
取而代之的是用一个更安全的方式来显示一个未知应用程序二进制文件的库文件依赖,使用 objdump
命令:
$ objdump -p /path/to/program | grep NEEDED
2. pldd
查看运行进程的共享库依赖关系
使用 pldd 命令
找出被一个运行中的进程载入的共享库,它会显示出在运行时被载入一个进程里的所有共享对象。
$ sudo pldd <PID>
注意你需要 root 权限去执行 pldd 命令。
或者,也可以选择 pmap
命令行工具报告一个进程的内存映射,也能显示出运行进程的库文件依赖。
$ sudo pmap <PID>