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

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

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

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

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

或者,用strace:

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

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

编辑:当然是…

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

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

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

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

 #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结构至less包含基地址和绝对文件名。 这是dlopen()用非NULL第一个参数实际返回的结构。 欲了解更多详情请参阅这里

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

ltrace似乎是你的朋友。

ltrace手册:

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

  Its use is very similar to strace(1). 

在solaris上也有pldd命令。

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