如果使用dlopen()再次加载相同的库,则会返回相同的文件句柄。
“相同的库”是什么意思?相同的文件名?相同的路径?相同的inode?相同的SONAME?还有吗这种行为如何与软链接交互?
假设我对ELF so和主流Linux发行版(Debian / Arch / RHEL系列)感兴趣。
后果示例:
答案 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;
出现在两个地方:
libfoo.so
)此外,短名称仅保存在 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
希望有帮助。