dlopen“相同库”的定义

时间:2019-09-24 16:00:00

标签: linux elf dlopen

根据dlopen(3) man page

  

如果使用dlopen()再次加载相同的库,则会返回相同的文件句柄。

“相同的库”是什么意思?相同的文件名?相同的路径?相同的inode?相同的SONAME?还有吗这种行为如何与软链接交互?

假设我对ELF so和主流Linux发行版(Debian / Arch / RHEL系列)感兴趣。

后果示例:

  • 如果“同一个库”的意思是“同一个SONAME”,那么我可以两次加载具有不同名称的同一个文件,并且只能得到一个句柄。如果“相同的库”的意思是“相同的文件名”,那么我可能会遇到符号冲突的情况。
  • 如果将符号链接返回到文件,并且“相同库”的意思是“相同文件名”,则到一个文件的多个符号链接是可以的,否则,如果使用符号链接的文件名,那么事情就太糟了。 / li>
  • 如果“相同库”的意思是“相同路径”,并且文件有两个路径(例如带有硬链接),则说明情况一片混乱,否则,如果“相同库”的意思是“相同inode”,则一切正常。

2 个答案:

答案 0 :(得分:3)

我决定深入研究 musl 的来源,以便对这些词进行可能的解释。有问题的函数是 load_library(),位于 https://github.com/ifduyue/musl/blob/3ab2a4e02682df1382955071919d8aa3c3ec40d4/ldso/dynlink.c#L990

“已加载”搜索 for (p=head->next; p; p=p->next) if (...) return p; 出现在两个地方:

  1. 首先是在非路径名的情况下,名称本身会被再次检查 dup 或短名称(短名称不是 soname,而是解析文件名的基本名称,如 libfoo.so
  2. 然后在一般路径中,在其中搜索设备和 inode 编号以查找 dup。值来自 fopen 句柄上的 fstat。

此外,短名称仅保存在 nom-path 情况下。


#2 案例似乎明确合并了硬链接。使用 fopen 也隐式地合并了符号链接。

ELF 文件本身从未因相同而被查阅过。所以这不是一团糟,但也不是超级聪明。


我现在太累了,无法阅读 glibc,但我无法想象那里有什么不寻常的地方。 Node.js 的 AIX polyfill 也使用 inode。

答案 1 :(得分:0)

我想说相同的库意味着相同的路径,我建立了一个小例子来说明:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    (void)argc, (void)argv;

    void (*hello)();

    void *handle = dlopen("./libhello.so", RTLD_NOW);
    printf("handle = %p\n", handle);

    void *handle2 = dlopen("libs/libhello.so", RTLD_NOW);
    printf("handle with different path = %p\n", handle2);

    // using symlink to libhello.so
    void *handle3 = dlopen("./symlink.so", RTLD_NOW);
    printf("handle with soft link = %p\n", handle3);

    if (handle == 0) {
        fprintf(stderr, "%s\n", dlerror());
        exit(1);
    }

    void *f = dlsym(handle, "hello");

    if (f) {
        hello = (void (*)())f;
        hello();
    }

    dlclose(handle);

    return 0;
} 

和共享库:

/* libhello.so */
#include <stdio.h>

void hello()
{
    printf("hello\n");
}

输出为:

handle = 0x217c030
handle with different path = 0x217ca40
handle with soft link = 0x217c030
hello

希望有帮助。