【问题标题】:Why would runpath be ignored?为什么会忽略运行路径?
【发布时间】:2019-04-16 14:56:54
【问题描述】:

在 CentOS 7.2 上,我使用 g++ 4.8.5 构建了一个无法运行的应用程序,因为它在其 runpath 中找不到确实存在的库。我很确定它在两周前有效。什么可能导致这种情况?

$ ./app
./app: error while loading shared libraries: libhdf5.so.9: cannot open shared object file: No such file or directory

$ ldd ./app | grep libhdf5
    libhdf5.so.9 => not found

$ readelf app -d | grep path
 0x000000000000001d (RUNPATH)            Library runpath: [/opt/ProductName/lib:/opt/ProductName/lib/private]

$ ll /opt/ProductName/lib/libhdf5.so*
lrwxrwxrwx. 1 fotechd fotechd      16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so -> libhdf5.so.9.0.0
lrwxrwxrwx. 1 fotechd fotechd      16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so.9 -> libhdf5.so.9.0.0
-rwxr-xr-x. 1 fotechd fotechd 3316074 Oct 26 14:35 /opt/ProductName/lib/libhdf5.so.9.0.0

设置LD_LIBRARY_PATH暂时修复它:

$ LD_LIBRARY_PATH=/opt/ProductName/lib ./app
...
OK

【问题讨论】:

  • 我在 Fedora 29 系统上遇到了完全相同的问题。你解决了吗?

标签: shared-libraries ld rpath


【解决方案1】:

我已经能够解决这个问题。对我来说,这是因为 not found 库是间接库,runpath 实际上并没有解决间接依赖关系。我通过将附加的-Wl,--disable-new-dtags 链接器选项传递给编译器,使用rpath 而不是runpath 来修复它。

这里有很好的详细解释:How to set RPATH and RUNPATH with GCC/LD?

【讨论】:

  • 所以你的意思是如果你的应用加载一个.so,它加载另一个.so,第二个.so不受运行路径的影响(但受rpath的影响)?
  • 就我而言,我无法判断哪些依赖项是间接的,因为ldd 只显示一个平面列表(而且我是代码库的新手)。要获得正确的树结构,您需要调用 lddtree,它是 pax-utils 的一部分(在 CentOS 上,我使用 sudo yum install pax-utils --enablerepo=epel 得到它)。
  • 是的,这正是间接依赖的含义:“由 .so 加载的 .so”。就我而言,未找到的 .so 不在您使用 readelf -d 获得的(需要)库列表中
【解决方案2】:

为了找到共享对象,dlopen() 按以下顺序搜索以下内容:

  • 链接二进制文件时使用 -rpath 选项设置为 ld 的运行时库搜索路径(请参阅实用程序参考)
  • LD_LIBRARY_PATH 环境变量指定的目录
  • _CS_LIBPATH 配置字符串指定的目录

似乎dlopen() 没有检查RUNPATH

http://www.qnx.com/developers/docs/6.5.0SP1.update/com.qnx.doc.neutrino_lib_ref/d/dlopen.html

【讨论】:

    猜你喜欢
    • 2014-07-10
    • 2020-09-13
    • 2012-06-26
    • 1970-01-01
    • 2010-11-12
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多