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

时间:2011-02-24 10:36:10

标签: c++ c linux shared-libraries

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

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

8 个答案:

答案 0 :(得分:73)

其他人走在正确的轨道上。以下是几种方式。

cat /proc/NNNN/maps | awk '{print $6}' | grep '\.so' | sort | uniq

或者,用strace:

strace CMD.... 2>&1 | grep '^open(".*\.so"'

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

修改当然还有lsof ...

lsof -p NNNN | awk '{print $9}' | grep '\.so'

答案 1 :(得分:13)

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

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

答案 2 :(得分:10)

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

#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;
}

link_map结构至少包含基址和绝对文件名。它是dlopen()实际返回的非NULL第一个参数的结构。有关详细信息,请参阅here

答案 3 :(得分:6)

ltrace似乎是你的朋友。

来自ltrace手册:

  

ltrace是一个简单的程序   运行指定的命令,直到它              退出。它拦截并记录动态库调用   哪个是              被执行过程调用,信号是   收到的              那个过程。它还可以拦截和打印系统调用   可执行程序-              由该计划提供。

       Its use is very similar to strace(1).

答案 4 :(得分:5)

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

答案 5 :(得分:3)

在solaris上还有pldd命令。

答案 6 :(得分:2)

您可以在Linux上以编程方式进行操作。您可以使用函数dl_iterate_phdr

这是从手册页中摘录的一个小例子:

#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>

static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
    int j;

   printf("name=%s (%d segments)\n", info->dlpi_name,
        info->dlpi_phnum);

   for (j = 0; j < info->dlpi_phnum; j++)
         printf("\t\t header %2d: address=%10p\n", j,
             (void *) (info->dlpi_addr + info->dlpi_phdr[j].p_vaddr));
    return 0;
}

int
main(int argc, char *argv[])
{
    dl_iterate_phdr(callback, NULL);

   exit(EXIT_SUCCESS);
}

答案 7 :(得分:1)

strace会跟踪正在打开的库文件吗?