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

有没有办法来检查哪些库是一个正在运行的进程使用?

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

Solutions Collecting From Web of "如何检查运行时为给定进程加载哪些共享库?"

其他人在正确的轨道上。 这里有几个方法。

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

或者,用strace:

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

这两种都假定共享库的路径中有“.so”,但是你可以修改它。 第一个输出相当漂亮,只是一个库列表,每行一个。 第二个会在打开时继续列出库,这样很好。

编辑:当然是…

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

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

编辑:运行, lsof -p <pid> ,列出各种有用的信息,例如,如果进程是java,列出所有打开的罐子 – 非常酷…

其实,你可以用下面的方法在代码中做到这一点:

 #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第一个参数实际返回的结构。 欲了解更多详情请参阅这里

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

ltrace似乎是你的朋友。

ltrace手册:

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

  Its use is very similar to strace(1). 

在solaris上也有pldd命令。

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