如何知道我的程序在运行时实际使用的共享库?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何知道我的程序在运行时实际使用的共享库?相关的知识,希望对你有一定的参考价值。

如何确定程序在运行时使用的共享库的路径?

我有glibc 2.12作为我的CentOS 6.10系统上运行的主要glibc,并且在installed中也有/opt/glibc-2.14 glibc 2.14。

当我检查我的可执行文件时

$ objdump -p ./myProgram

它给出了这个信息

Dynamic Section:
NEEDED               libpthread.so.0
NEEDED               libcurl.so.4
NEEDED               libc.so.6

而我的LD_LIBRARY_PATH有这个价值/opt/glibc-2.14/lib

有没有看到我的程序在运行时实际使用哪个libc.so.6库(可能带有库文件的路径)?

答案

在Linux上:一种可能的方法是查看/proc/文件系统中的相应条目。例如,对于具有PID X的程序,您可以在/proc/X/maps中找到类似于以下内容的信息:

...
7f34a73d6000-7f34a73f8000 r--p 00000000 08:03 18371015                   /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc-2.27.so
7f34a73f8000-7f34a7535000 r-xp 00022000 08:03 18371015                   /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc-2.27.so
...

它清楚地显示了我的libc(该程序使用的libc)的位置。


Example(缺少一些错误处理!)来显示fopen来自哪里:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>

#define BSIZE 200

int main(void) {
    char buffer[BSIZE];
    int const pid = getpid();
    snprintf(buffer, BSIZE, "/proc/%d/maps", pid);
    FILE * const maps = fopen(buffer, "r");
    while (fgets(buffer, BSIZE, maps) != NULL) {
        unsigned long from, to;
        int const r = sscanf(buffer, "%lx-%lx", &from, &to);
        if (r != 2) {
            puts("!");
            continue;
        }
        if ((from <= (uintptr_t)&fopen) && ((uintptr_t)&fopen < to)) {
            char const * name = strchr(buffer, '/');
            if (name) {
                printf("%s", name);
            } else {
                puts("?");
            }
        }
    }
    fclose(maps);
}

以上是关于如何知道我的程序在运行时实际使用的共享库?的主要内容,如果未能解决你的问题,请参考以下文章

如何找出在 Linux 上运行 Java 类需要哪些共享库?

如何使用自动工具构建静态和共享库?

如何使共享库符号强大?

如何在运行时读取共享库数据段开头的绝对加载地址?

不同版本的共享库

仅在按照意图进行时才更改片段(在这种情况下,他们实际上共享应用程序)