有没有办法检查哪些库是正在运行的进程?
更具体地说,如果程序使用dlopen加载某些共享库,则readelf或ldd不会显示它。 是否有可能从正在运行的进程中获取该信息?如果是,怎么样?
答案 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
会跟踪正在打开的库文件吗?