【发布时间】:2018-09-04 13:03:58
【问题描述】:
所以有点历史,我有 3 个库:
- “lib1.so”没有依赖项
- 与“lib1.so”链接的“lib2.so”
- “test”可执行程序,无依赖关系
我需要的是在运行时通过“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,忽略它
【问题讨论】:
-
“这不起作用” - 当你尝试时会发生什么? lib1 和 lib2 是否总是在同一目录中?
-
@JohnZwinck,我更新了问题
-
你能用
LD_DEBUG=all跑吗? -
@yugr 查看更新,lib2.so 加载了两次。怎么样?
-
@AlekDepler 请为首次加载
lib1.so添加日志(在opening file=/usr/local/test/lib1.so [0]之后)。我们需要了解为什么链接器无法从/usr/local/test加载它,这是您问题的根本原因。