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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5103443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:23:06  来源:igfitidea点击:

How to check what shared libraries are loaded at run time for a given process?

c++clinuxshared-libraries

提问by B?ови?

Is there a way to check which libraries is a running process using?

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

To be more specific, if a program loads some shared libraries using dlopen, then readelf or ldd is not going to show it. Is it possible at all to get that information from a running process? If yes, how?

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

采纳答案by Dietrich Epp

Other people are on the right track. Here are a couple ways.

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

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

Or, with strace:

或者,使用 strace:

strace CMD.... 2>&1 | grep -E '^open(at)?(.*\.so'

Both of these assume that shared libraries have ".so" somewhere in their paths, but you can modify that. The first one gives fairly pretty output as just a list of libraries, one per line. The second one will keep on listing libraries as they are opened, so that's nice.

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

And of course lsof...

当然lsof...

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

回答by Nim

May be lsof- the swiss army knife of linux will help?

可能是lsof——Linux 的瑞士军刀会有所帮助吗?

edit: to run, lsof -p <pid>, lists all sorts of useful information, for example, if the process is java, lists all the open jars - very cool...

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

回答by Martin Broadhurst

Would stracetrace the library file being opened?

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

回答by chaos.ct

ltraceseems to be your friend.

ltrace似乎是你的朋友。

From ltracemanual:

ltrace手册:

ltrace is a program that simply runs the specified command until it exits. It intercepts and records the dynamic library calls which are called by the executed process and the signals which are received by that process. It can also intercept and print the system calls exe‐ cuted by the program.

       Its use is very similar to strace(1).

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

       Its use is very similar to strace(1).

回答by Kieron

On Linux, /proc/<processid>/mapscontains a list of all the files mapped into memory, which I believe should include any loaded by dlopen().

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

回答by Christian.K

On solaris there is also the pldd command.

在solaris 上还有pldd 命令。

回答by abyss.7

Actually, you can do this in your code in the following way:

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

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

The link_mapstructure contains at least the base address and the absolute file name. It's the structure that is actually returned by dlopen()with non-NULL first argument. For more details see here.

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

回答by Nicolas Dusart

You can do so programmatically on Linux. You can use the function dl_iterate_phdr.

您可以在 Linux 上以编程方式执行此操作。您可以使用该功能dl_iterate_phdr

Here is a small example taken from the man page :

这是取自手册页的一个小例子:

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