首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么相同的可执行文件对于不同的库查找使用不同的RUNPATHs?

为什么相同的可执行文件对于不同的库查找使用不同的RUNPATHs?
EN

Stack Overflow用户
提问于 2018-10-25 16:05:34
回答 1查看 315关注 0票数 3

我有一个Linux C++程序,它可以构建&链接(使用-Wl,--no-undefined ),但是当我尝试运行它时却无法加载它的所有库。我一直试图用ldd检查它的依赖关系,但我不知道为什么它会被失败的库绊倒:

代码语言:javascript
复制
$ ldd standalone_test
   ...  lots of libraries that are found ...
libPythia6.so => not found

现在,根据嵌入在可执行文件中的RUNPATH,应该在一个地方找到这个库:

代码语言:javascript
复制
$ readelf -d ./standalone_test | grep "RUNPATH"
 0x000000000000001d (RUNPATH)            Library runpath: [/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug]
$ ls /opt/genie/GENIESupport/pythia6/v6_424/lib
liblund.a  libPythia6.so  pydata.o

(可执行的standalone_test和库libPythia6.so都是ELF64,所以我不认为这是处理器体系结构不匹配之类的。)

我已经尝试深入了解在库加载期间发生了什么,并且我注意到在同一个可执行文件下加载不同库(其中一些是由可执行文件请求的库请求的“链”加载)报告了不同的RUNPATH

代码语言:javascript
复制
$ LD_DEBUG=libs,files ./standalone_test 2>&1 | ack RUNPATH
  # this one is the 'correct' RUNPATH (the one from the executable)
 19553:  search path=/opt/root/lib/tls/haswell/x86_64:/opt/root/lib/tls/haswell:/opt/root/lib/tls/x86_64:/opt/root/lib/tls:/opt/root/lib/haswell/x86_64:/opt/root/lib/haswell:/opt/root/lib/x86_64:/opt/root/lib        (RUNPATH from file ./standalone_test)
 # next one has been 'augmented' with processor architecture subdirs
 19553:  search path=/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/tls:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/haswell:/home/jeremy/code/NOvARwgt/cmake-build-debug/src/x86_64:/home/jeremy/code/NOvARwgt/cmake-build-debug/src:/home/jeremy/code/genie-2.12.2/lib/tls/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls/haswell:/home/jeremy/code/genie-2.12.2/lib/tls/x86_64:/home/jeremy/code/genie-2.12.2/lib/tls:/home/jeremy/code/genie-2.12.2/lib/haswell/x86_64:/home/jeremy/code/genie-2.12.2/lib/haswell:/home/jeremy/code/genie-2.12.2/lib/x86_64:/home/jeremy/code/genie-2.12.2/lib:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/tls:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib/haswell:/opt/genie/GENIESupport/pythia6/v6_424/lib/x86_64:/opt/genie/GENIESupport/pythia6/v6_424/lib:/opt/root/lib:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/tls:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/haswell:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug/x86_64:/cvmfs/nova-development.opensciencegrid.org/novasoft/releases/development/lib/Linux2.6-GCC-debug      (RUNPATH from file ./standalone_test)
    ... more variants of these two ...
 # this one contains only a single entry from the real runpath??
 19553:  search path=/opt/root/lib      (RUNPATH from file ./standalone_test)

在最后一种情况下,库不被定位,可执行文件由于cannot open shared object file: No such file or directory错误而失败,它也将继续查看系统搜索路径。

我的问题是:RUNPATH 上的这些变体是如何配制的?--据我所知,它们是由请求它们的各种库修改的,但我似乎在googleweb上找不到任何解释。(也许我在寻找错误的东西?)如果我理解了这里发生了什么,我就能倒过来理解为什么库一开始就找不到了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-28 18:11:26

我的问题是: RUNPATH上的这些变体是如何配制的?

与较早的RPATH不同,RUNPATH仅在搜索二进制文件的直接依赖项时应用。

也就是说,如果a.outRUNPATH of /fooNEEDED of libfoo.so (位于/foo中),那么libfoo.so就会被找到。但是如果libfoo.so本身依赖于libbar.so (也位于/foo中),而如果libfoo.so没有RUNPATH,那么就找不到libbar.so

这种行为促进“每个ELF二进制应该是自给自足的”。在上述情况下,libfoo.so不是自给自足的(需要libbar.so,但没有说明在哪里可以找到它)。

如果您使用RPATH,那么那里的路径将适用于每个搜索,libbar.so也会被找到。在链接-Wl,--disable-new-dtags时,您可以使用a.out实现这一点。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52993692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档