如何查找进程用到的动态库

在Linux系统中,查看进程使用的动态库(共享库)有多种方法,以下是几种常用且高效的方式:


方法1:通过 /proc 文件系统(推荐)

步骤:

  1. 获取目标进程的PID(例如通过 ps -ef | grep 进程名 查询)
  2. 直接查看进程的内存映射文件:
    1
    cat /proc/<PID>/maps | grep '\.so'
    示例:
    1
    cat /proc/1234/maps | grep '\.so'
    输出特点:
    显示所有加载的.so文件及其内存地址,清晰易读。

方法2:使用 lsof 命令

命令:

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

示例:

1
lsof -p 1234 | grep '\.so'

输出特点:
列出进程打开的所有.so文件(包括完整路径),适合查看详细信息。


方法3:使用 pmap 命令

命令:

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

示例:

1
pmap 1234 | grep '\.so'

输出特点:
显示内存映射,包含库文件路径和占用大小。


⚠ 注意:避免直接使用 ldd

  • ldd 用于查看可执行文件的依赖库,而非运行中的进程:
    1
    ldd /path/to/executable
  • 安全风险: ldd 可能触发程序执行,对未知程序慎用!

完整操作流程示例

  1. 查找进程PID:

    1
    ps -ef | grep nginx

    输出示例:master 1234 ... nginx: master process

  2. 查看该进程加载的库:

    1
    2
    3
    cat /proc/1234/maps | grep '\.so'  # 方法1
    lsof -p 1234 | grep '\.so' # 方法2
    pmap 1234 | grep '\.so' # 方法3

输出结果解读

  • 典型输出示例:
    1
    7f3a1b2e5000-7f3a1b4a0000 r-xp 00000000 08:01 114060  /usr/lib/libcrypto.so.1.1
    • 7f3a1b2e5000-7f3a1b4a0000:库在内存中的地址范围
    • r-xp:内存权限(可读、可执行、私有)
    • /usr/lib/libcrypto.so.1.1:库文件路径

特殊情况处理

  1. 缺失库文件?
    检查路径是否存在,或使用 ldconfig -p | grep 库名 查找系统已知库。
  2. 无权限查看进程?
    使用 sudo 提权执行命令。

总结

方法 命令 适用场景
/proc/PID/maps cat /proc/1234/maps | grep '\.so' 最直接、无需额外工具
lsof lsof -p 1234 | grep '\.so' 查看文件详细信息
pmap pmap 1234 | grep '\.so' 同时显示内存占用大小

根据需求选择合适方法,推荐优先使用 /proc 文件系统!

Linux下检查进程用到了哪些动态库的接口

在 Linux 下检查进程实际调用的动态库接口(函数),有以下几种有效方法:

方法 1:使用 ltrace 工具(实时跟踪库函数调用)

1
sudo ltrace -p <PID> -s 999 -o trace.log
  • 作用:实时捕获进程调用的动态库函数
  • 参数说明
    • -p <PID>:指定目标进程 ID
    • -s 999:显示完整函数参数(避免截断)
    • -o trace.log:输出到文件
  • 示例输出
    1
    2
    libc.so.6->printf("Hello %s\n", "World") = 13
    libpthread.so.0->pthread_mutex_lock(0x7f8a5c3dee80) = 0
  • 优点:直接显示实际调用的函数及参数
  • 缺点:会产生性能开销,不适合生产环境

方法 2:使用 perf(性能分析工具)

1
2
3
4
5
# 记录函数调用
sudo perf record -p <PID> -g -- sleep 30

# 查看报告
sudo perf report -n --stdio
  • 作用:采样分析函数调用栈
  • 关键参数
    • -g:记录调用关系
    • -- sleep 30:采样时长(秒)
  • 输出特点
    1
    2
    3
    Samples: 5K of event 'cycles'
    62.3% [libcrypto.so.1.1] EVP_DecryptUpdate
    28.1% [libssl.so.1.1] SSL_read
  • 优点:性能开销小,适合生产环境
  • 进阶:生成火焰图
    1
    perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svg

方法 3:使用 GDB(调试器)

1
2
3
4
5
6
gdb -p <PID>
(gdb) set logging file gdb_trace.log
(gdb) set logging on
(gdb) bt
(gdb) info functions
(gdb) continue
  • 操作说明
    1. bt:查看当前调用栈
    2. info functions:列出所有已加载函数
    3. Ctrl+C 中断后再执行命令
  • 优点:可交互式检查任意时刻的函数调用
  • 缺点:会暂停进程执行

方法 4:查看动态符号表(静态分析)

1
2
3
4
5
6
7
8
# 1. 找到进程加载的库
cat /proc/<PID>/maps | grep '\.so'

# 2. 查看库的导出函数
readelf -sW /path/to/library.so | grep FUNC

# 3. 查看二进制依赖的符号
nm -D --undefined-only /path/to/executable
  • 关键命令
    • readelf -sW:显示动态符号表(过滤 FUNC
    • nm -D --undefined-only:显示未定义的符号(需动态解析的函数)
  • 示例
    1
    2
    3
    readelf -sW /lib/x86_64-linux-gnu/libc.so.6 | 
    awk '$4 == "FUNC" && $5 != "LOCAL" && $7 !~ /^UND/ {print $8}' |
    sort

方法 5:使用 bpftrace(eBPF 高级跟踪)

1
2
# 跟踪所有动态库函数调用
sudo bpftrace -e 'uprobe:/*.so:* { printf("%s->%s\n", probe); }' -p <PID>
  • 示例输出
    1
    2
    libc.so.6:malloc
    libssl.so.1.1:SSL_write
  • 优点:高性能内核级跟踪
  • 进阶脚本(带参数):
    1
    bpftrace -e 'uprobe:/usr/lib/libc.so.6:malloc { printf("malloc(%d)\n", arg0); }'

结果分析技巧

  1. 过滤常用库
    1
    ltrace -p <PID> | grep -E 'lib(c|pthread|ssl|stdc\+\+)'
  2. 统计高频函数
    1
    ltrace -c -p <PID>  # 显示调用统计
  3. 定位具体库
    1
    2
    # 查看 SSL 相关函数
    ltrace -p <PID> | grep -i ssl_

各方法对比

方法 实时性 性能影响 详细程度 适用场景
ltrace 实时 函数+参数 调试、短期监控
perf 采样 中低 调用栈 性能分析、生产环境
GDB 暂停 最详细 深度调试
符号表分析 静态 潜在函数 预研、安全审计
bpftrace 实时 可定制 高级跟踪、生产诊断

注意:动态库函数调用检查需要 root 权限(sudo),且可能影响进程性能,生产环境建议使用 perfbpftrace 等低开销工具。