gpt4 book ai didi

linux - 在 Linux 中强制动态链接器在运行时加载库

转载 作者:太空宇宙 更新时间:2023-11-04 10:10:17 24 4
gpt4 key购买 nike

那么一点点历史,我有 3 个库:

  • 没有依赖项的“lib1.so”
  • 与“lib1.so”链接的“lib2.so”
  • “测试”无依赖性的可执行程序

我需要的是在运行时通过“dlopen”方法从“test”可执行文件动态加载“lib2.so”。问题是“lib1.so”无法自动加载,因为链接器不知道在哪里可以找到它。

我一开始尝试加载“lib1.so”:

void* ptr_lib1 = dlopen("/usr/local/test/lib1.so", RTLD_NOW | RTLD_GLOBAL);
void* ptr_lib2 = dlopen("/usr/local/test/lib2.so", RTLD_NOW | RTLD_GLOBAL);

但由于某种原因这不起作用,它在调用第二个 dlopen 后给我错误(来自 dlerror 的文本):

"lib1.so: cannot open shared object file: No such file or directory"

这意味着“lib1.so”试图加载两次:第一次是为“lib1.so”调用 dlopen,第二次是为“lib2.so”调用 dlopen。

谁能解释为什么以及如何解决这个问题?请不要建议在启动可执行文件之前修改 LD_LIBRARY_PATH。也不建议修改可执行文件的链接器标志。我需要能够在运行时从任何文件夹加载该库。

更新。经过一些研究,我这样做了:

LD_DEBUG=all ./test

并且发现库 lib1.so 试图加载两次(第一次是在我调用 dlopen 时,第二次是在 LD 尝试解析 lib2.so 的依赖项时):

add /usr/local/test/lib1.so [0] to global scope
opening file=/usr/local/test/lib1.so [0]; direct_opencount=1
...
30031: file=lib1.so [0]; needed by /usr/local/test/lib2.so [0]
30031: find library=lib1.so [0]; searching
30031: search path=./tls/x86_64:./tls:./x86_64:. (RPATH from file ./test)
30031: trying file=./tls/x86_64/lib1.so
30031: trying file=./tls/lib1.so
30031: trying file=./x86_64/lib1.so
30031: trying file=./lib1.so
30031: search cache=/etc/ld.so.cache
30031: search path=/lib64/tls/x86_64:/lib64/tls:/lib64/x86_64:/lib64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64:/usr/lib64 (system search path)
30031: trying file=/lib64/tls/x86_64/lib1.so
30031: trying file=/lib64/tls/lib1.so
30031: trying file=/lib64/x86_64/lib1.so
30031: trying file=/lib64/lib1.so
30031: trying file=/usr/lib64/tls/x86_64/lib1.so
30031: trying file=/usr/lib64/tls/lib1.so
30031: trying file=/usr/lib64/x86_64/lib1.so
30031: trying file=/usr/lib64/lib1.so
30031:
30031:
30031: file=/usr/local/test/lib2.so [0]; destroying link map

还是不明白是怎么回事...

UPDATE2. 有完整的 LD_DEBUG log

注意:还有一个库lib_other.so,忽略即可

最佳答案

dlopen(3)失败,你应该使用 dlerror(3)获取一些有用的消息。

所以代码至少:

void* ptr_lib1 
= dlopen("/usr/local/test/lib1.so", RTLD_NOW | RTLD_GLOBAL);
if (!ptr_lib1) {
fprintf(stderr, "dlopen lib1 failure: %s\n", dlerror());
exit(EXIT_FAILURE);
}

其他dlopen也是如此

注意 dlerror给出了一个详细错误信息。如果您不明白,请将其放入您的问题中。

您可能忘记设置一些 rpath链接时lib1.solib2.so .或者您需要明确设置 LD_LIBRARY_PATH ,或运行 ldconfig

阅读 Drepper 的 How To Write Shared Libraries纸的详细信息。仔细阅读ld-linux(8)

dlopenlib2失败,因为它的依赖项 lib1没有找到。您需要修复该问题(通过 rpath、LD_LIBRARY_PATHldconfig 等...)

您可以添加一些 -Wl,-rpath,/usr/local/test/lib1.solib1选项等

您还可以(更简单地)决定将所有共享库放入 /usr/local/lib/你会在 /etc/ld.so.conf 中提到.然后你需要运行 ldconfig在每次添加库之后。

关于linux - 在 Linux 中强制动态链接器在运行时加载库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49490555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com