1

我有一个可执行文件,它依赖于两个基本的 boost 库,libboost_system并且libboost_thread,当可执行文件加载库时,搜索路径在以下方面令人费解地不同lib/tls

 $ LD_DEBUG=libs ./var.exe
 25130:     find library=libboost_system.so.1.55.0 [0]; searching
 25130:      search path=/opt/boost_1_55_0/stage/lib/tls/x86_64:/opt/boost_1_55_0/stage/lib/tls:/opt/boost_1_55_0/stage/lib/x86_64:/opt/boost_1_55_0/stage/lib         (RPATH from file ./var.exe)
 25130:       trying file=/opt/boost_1_55_0/stage/lib/tls/x86_64/libboost_system.so.1.55.0
 25130:       trying file=/opt/boost_1_55_0/stage/lib/tls/libboost_system.so.1.55.0
 25130:       trying file=/opt/boost_1_55_0/stage/lib/x86_64/libboost_system.so.1.55.0
 25130:       trying file=/opt/boost_1_55_0/stage/lib/libboost_system.so.1.55.0
 25130:
 25130:     find library=libboost_thread.so.1.55.0 [0]; searching
 25130:      search path=/opt/boost_1_55_0/stage/lib            (RPATH from file ./var.exe)
 25130:       trying file=/opt/boost_1_55_0/stage/lib/libboost_thread.so.1.55.0

可执行文件已与-rpath=/opt/...两个库的完全相同的设置链接,并且我知道 boost 是通过公共调用构建的b2(即两者的命令行参数完全相同)。/etc/ld.so.cache没有任何相关条目。

此外,就 rpath 或 ABI 要求而言,构建的库本身似乎没有什么特别之处,

$ readelf -d /opt/boost_1_55_0/stage/lib/libboost_system.so.1.55.0 | grep -i rpath
# empty
$ eu-readelf -h /opt/boost_1_55_0/stage/lib/libboost_system.so.1.55.0
# there is no difference in ABI versions

这两个库具有完全相同的共享库依赖项,除了依赖的事实libboost_threadlibboost_system并且都需要 GLIBC_2.2.5。

我认为已决定以libboost_system某种方式需要与NPTL glibc 链接,这<rpath>/lib/tls就是搜索的原因,但对于我来说,查看libboost_system库的 objdump 并不清楚为什么会这样。

如何标记 NPTL 库?dlopen(3) 如何决定查看 lib/tls 路径?

4

1 回答 1

0

搜索路径在 lib/tls 方面令人费解地不同

你在叫错树。

GLIBC 加载器RPATH从您的可执行文件中获取,并将PLATFORM字符串(tls/x86_64:tls:x86_64此处)附加到它以构建完整的搜索路径。

一旦加载器发现例如RPATH/tls目录不存在,它就会从搜索路径中删除该条目(重复搜索不存在的目录是没有意义的)。最终,你最终只剩下RPATH自己在场。

如果你重新链接你的二进制文件以例如反转依赖的顺序libboost_threadlibboost_system,你会再次发现只有第一个库被搜索RPATH/tls,等等,而第二个库只在RPATH.

于 2014-05-10T04:06:57.750 回答