【问题标题】:ldd says "not found" for one file, and found for anotherldd 对一个文件说“未找到”,而对另一个文件说“未找到”
【发布时间】:2021-02-10 16:17:35
【问题描述】:

我正在尝试收集一些 .so 文件所需的所有依赖项。我使用Recursive ldd 脚本,但这并不重要。

我想把所有的 .so 文件放在一个目录中,说是在

/home/user/project/lib

我有一个奇怪的经历:假设有一个文件 libmat.so 我想收集它的所有依赖项。于是我跑了

/home/user/project/lib$ ldd libmat.so
...
 libmwboost_system.so.1.65.1 => /home/user/project/lib/libmwboost_system.so.1.65.1
 libmwboost_filesystem.so.1.65.1 => /home/user/project/lib/libmwboost_filesystem.so.1.65.1
 ...

所以我们看到ldd 识别了当前目录中的libmwboost_system.so.1.65.1 文件。
原来libmwboost_filesystem.so.1.65.1.so 也依赖于libmwboost_system.so.1.65.1, 但是当我运行时:

/home/user/project/lib$ ldd libmwboost_filesystem.so.1.65.1
...
 libmwboost_system.so.1.65.1 => not found
 ...

为什么lddlibmat.so 上运行时可以找到它,而在libmwboost_filesystem.so.1.65.1 上运行时却找不到?

如果有人可以在链接过程的上下文中提供解释,我会很高兴。据我所知,当您将文件链接到库时,您使用以下标志:

~$ gcc my_program.c -Lpath/to/solib/for/static/linker -lnameoflib -wl,-rpath=path/to/solib/for/dynamic/linker

这个-Wl,-rpath 标志在可执行文件中嵌入了动态链接器将在运行时搜索的库的路径。对于依赖于其他库的共享库 - 它的工作方式是否相同?

【问题讨论】:

    标签: linker shared-libraries


    【解决方案1】:

    好的,这就是它的工作原理:

    在将二进制文件(无论是可执行文件还是其他共享库)链接到共享库时,静态链接器会在二进制文件中嵌入我们链接的库的名称。一旦用户运行程序,这些库将由动态链接器 - ld.so 加载。

    现在的问题是动态链接器将在运行时搜索这些库的位置。简而言之,根据ld.so 的手册页,当动态链接器首先检查二进制文件以解析其依赖项时,它会遍历依赖项的字符串。如果字符串包含斜杠“/”,则该字符串被解释为路径。如果在链接时使用斜杠指定库名称,可能会发生这种情况,如下所示:

    ~$ gcc prog.c ../path/to/library.so
    

    在这种情况下,嵌入在可执行文件中的字符串将为:../path/to/library.so,动态链接器将相对于二进制文件的位置搜索它。

    如果没有,它将在位置列表中搜索库(整个列表在手册页中指定)。第一个位置是二进制文件的 DT_RUNPATH 部分属性中指定的目录。这可以在链接时使用-Wl,-rpath 标志设置:

    ~$ gcc prog.c -Lpath/of/lib/ -lmylib -Wl,-rpath=path/of/lib
    

    在这种情况下,path/of/lib 将由动态库搜索库。

    您可以使用 readelf 检查此属性:

    ~$ readelf -d binary | grep RUNPATH
    

    在我的例子中,libmat.so 库包含设置为$ORIGIN 的 RUNPATH 属性,这意味着将在二进制库的相同位置搜索库。而libmwboost_filesystem.so.1.65.1 没有设置此属性,这就是ldd 找不到库的原因。

    ldd 只是使用ld.so 尝试加载库,并根据ld.so 手册页中指定的搜索路径显示找到它们的位置。

    【讨论】:

      猜你喜欢
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2018-05-14
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多