Linux下如何判断so动态库是否已加载

在Linux下,判断一个共享库(.so文件)是否已被加载,可以通过以下几种方法实现:


方法1:检查 /proc/<PID>/maps 文件

每个进程的内存映射信息都存储在 /proc/<PID>/maps 文件中,其中 <PID> 是进程ID。

  1. 找到目标进程的PID
    1
    ps aux | grep <进程名>
  2. 检查库是否加载
    1
    cat /proc/<PID>/maps | grep '库名\.so'
    示例(检查进程 nginx 是否加载 libcrypt.so):
    1
    cat /proc/$(pgrep nginx | head -1)/maps | grep libcrypt.so
    • 若有输出,则表示库已加载。

方法2:使用 lsof 命令

lsof 可以列出被进程打开的文件(包括共享库):

1
lsof -p <PID> | grep '库名\.so'

示例

1
lsof -p $(pgrep firefox) | grep libz.so

方法3:使用 pmap 命令

pmap 显示进程的内存映射:

1
pmap <PID> | grep '库名\.so'

示例

1
pmap $(pidof bash) | grep libdl.so

方法4:编程方式(C/C++)

在代码中通过 dlopenRTLD_NOLOAD 标志检查库是否已加载:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <dlfcn.h>
#include <stdio.h>

int main() {
void *handle = dlopen("libexample.so", RTLD_LAZY | RTLD_NOLOAD);
if (handle) {
printf("库已加载\n");
dlclose(handle); // 注意:仅减少引用计数,不卸载库
} else {
printf("库未加载: %s\n", dlerror());
}
return 0;
}

编译

1
gcc -o check_so check_so.c -ldl

方法5:使用 gdb 调试器

附加到进程并检查共享库:

1
gdb -p <PID> -ex "info sharedlibrary" -ex "quit"

示例

1
gdb -p $(pidof sshd) -ex "info sharedlibrary" -ex "quit" | grep 'libcrypto.so'

方法6:全局检查(所有进程)

检查系统中是否有任意进程加载了目标库:

1
grep '库名\.so' /proc/*/maps

示例

1
grep 'libssl.so' /proc/*/maps

注意事项

  1. 路径匹配
    库可能以完整路径或部分名称显示(如 /usr/lib/libc.solibc.so),建议使用模糊匹配(如 grep -i "libname")。
  2. 动态加载
    通过 dlopen() 动态加载的库也会出现在 /proc/<PID>/maps 中。
  3. 权限问题
    查看其他用户的进程需要 root 权限(如 sudo lsof)。
  4. 库版本差异
    不同版本的库可能有不同文件名(如 libfoo.so.1),需匹配实际名称。

总结

场景 推荐方法
快速检查单个进程 cat /proc/<PID>/maps | grep ...
检查所有进程 grep 'lib.so' /proc/*/maps
编程实现 dlopen + RTLD_NOLOAD
命令行实时检查 lsofpmap

根据需求选择合适的方法即可高效判断动态库是否被加载。