我想知道系统会在哪里搜索动态库。我们以nxclient为例。例如, ldd /usr/NX/bin/nxclient 给了我一些输出
libpng12.so.0 => /usr/NX/lib/libpng12.so.0 (0x00007fcb4a16f000)
Run Code Online (Sandbox Code Playgroud)
现在为什么系统选择 /usr/NX/lib/libpng12.so.0 而不是 /usr/lib64/libpng12.so.0?两者都存在。这是在哪里配置的?/etc/ld.so.conf* 不包含 /usr/NX 并且我的 $LD_LIBRARY_PATH 为空。
库路径可能被硬编码在二进制文件中。
\n\n\n\n\n\n\nGNU C 库的动态链接器及其衍生的嵌入式 GLIBC 实现了一个相当复杂的搜索共享库的算法。基本搜索顺序是:
\n\n\n
\n- 二进制文件的 DT_RPATH 动态节属性中的(以冒号分隔的)路径(如果存在)且 DT_RUNPATH 属性不存在。
\n- 环境变量 LD_LIBRARY_PATH 中的(冒号分隔的)路径,除非可执行文件是 setuid/setgid 二进制文件,在这种情况下它将被忽略。LD_LIBRARY_PATH 可以通过使用选项 --library-path 调用动态链接器来覆盖(例如\n /lib/ld-linux.so.2 --library-path $HOME/mylibs myprogram)。
\n- 二进制文件的 DT_RUNPATH 动态节属性中的(冒号分隔的)路径(如果存在)。
\n- 基于 ldconfig 缓存文件(通常位于 /etc/ld.so.cache)进行查找,该文件包含先前在增强库路径中找到的候选库的编译列表(由 /etc/ld.so.conf 设置) )。但是,如果二进制文件是使用 -z\n nodeflib 链接器选项链接的,则将跳过默认库路径中的库。
\n- 在受信任的默认路径 /lib 中,然后在 /usr/lib 中。如果二进制文件是使用 -z nodeflib 链接器选项链接的,则将跳过此步骤。
\n
要查看二进制文件是否配置了 RPATH:
\n\n\n\n\nreadelf -d filename 仅显示 \xe2\x80\x9cdynamic\xe2\x80\x9d 部分中的数据
\n\n标头的 \xe2\x80\x9cdynamic\xe2\x80\x9d 部分很有趣,因为它包含初始加载过程中使用的数据,例如:
\n\nRun Code Online (Sandbox Code Playgroud)\nNEEDED: libraries needed by this module\nRPATH: See \xe2\x80\x9cLoader search procedure\xe2\x80\x9d below\nSONAME: If this module is a library, this item shows the \xe2\x80\x9csoname\xe2\x80\x9d of the library.\n
来源:linux 加载器,以及它如何查找库:ld-linux 等
\n\n要查看 ldconfig 缓存中的所有库,您可以运行
\n\nldconfig -p\n
Run Code Online (Sandbox Code Playgroud)\n\n在二进制文件中设置 RUNPATH 的示例
\n\n$ readelf -d /opt/teamviewer9/tv_bin/TVGuiSlave.64 | grep -i RUNPATH\n 0x000000000000001d (RUNPATH) Library runpath: [${ORIGIN}/../lib]\n
Run Code Online (Sandbox Code Playgroud)\n