如何检查在给定进程的运行时加载了哪些共享库?

BЈо*_*вић 47 c c++ linux shared-libraries

有没有办法检查哪些库是正在运行的进程?

更具体地说,如果程序使用dlopen加载某些共享库,则readelf或ldd不会显示它.是否有可能从正在运行的进程中获取该信息?如果有,怎么样?

Die*_*Epp 75

其他人走在正确的轨道上.这里有几种方法.

cat /proc/NNNN/maps | awk '{print $6}' | grep '\.so' | sort | uniq
Run Code Online (Sandbox Code Playgroud)

或者,与strace:

strace CMD.... 2>&1 | grep '^open(".*\.so"'
Run Code Online (Sandbox Code Playgroud)

这两个都假设共享库在其路径中的某处有".so",但您可以修改它.第一个提供相当漂亮的输出,只是一个库列表,每行一个.第二个将继续列出库,因为这是很好的.

编辑:当然lsof......

lsof -p NNNN | awk '{print $9}' | grep '\.so'
Run Code Online (Sandbox Code Playgroud)

  • 此外,`strace -f`最适合生成子进程 (4认同)

Nim*_*Nim 15

可能lsof- linux的瑞士军刀会有帮助吗?

编辑:运行,lsof -p <pid>列出所有类型的有用信息,例如,如果进程是java,列出所有打开的jar - 非常酷......


aby*_*s.7 11

实际上,您可以通过以下方式在代码中执行此操作:

#include <link.h>

using UnknownStruct = struct unknown_struct {
   void*  pointers[3];
   struct unknown_struct* ptr;
};
using LinkMap = struct link_map;

auto* handle = dlopen(NULL, RTLD_NOW);
auto* p = reinterpret_cast<UnknownStruct*>(handle)->ptr;
auto* map = reinterpret_cast<LinkMap*>(p->ptr);

while (map) {
  std::cout << map->l_name << std::endl;
  // do something with |map| like with handle, returned by |dlopen()|.
  map = map->l_next;
}
Run Code Online (Sandbox Code Playgroud)

link_map结构至少包含基址和绝对文件名.它dlopen()是非NULL第一个参数实际返回的结构.欲了解更多详情,请参见这里.


cha*_*.ct 7

ltrace 似乎是你的朋友.

来自ltrace手册:

ltrace是一个只运行指定命令直到它退出的程序.它拦截并记录由执行过程调用的动态库调用以及该进程接收的信号.它还可以拦截和打印程序执行的系统调用.

       Its use is very similar to strace(1).
Run Code Online (Sandbox Code Playgroud)


Kie*_*ron 6

在Linux上,/proc/<processid>/maps包含映射到内存中的所有文件的列表,我认为应该包含任何加载的文件dlopen().