我正在尝试在 Debian 8 来宾操作系统(OpenVZ 容器化环境)上设置和运行科学应用程序。由于操作系统捆绑的 GNU C++ 库相当旧,并且不包含所有需要的符号,因此我创建了一个特殊的目录来包含较新版本的库,libstdc++.so.6
并将环境变量设置LD_LIBRARY_PATH
为指向该目录。另外,我已确保目标应用程序没有设置 SUID 权限(因为在这种情况下,LD_LIBRARY_PATH
在某些平台上可能会被忽略)。尽管如此,ldd <APP_EXECUTABLE>
命令仍然显示它使用默认系统位置/usr/lib/x86_64-linux-gnu
。为什么LD_LIBRARY_PATH
会被忽视?
PS我也尝试过使用LD_PRELOAD
环境变量,但它也被忽略了。
答案1
该命令检查标准系统库目录(通常是/lib
和/usr/lib
)以及/etc/ld.so.conf
file 和/或files 中定义的任何目录的内容,并将结果缓存在.每当您安装或删除库包时,包管理工具通常会自动运行该命令。/etc/ld.so.conf.d/*.conf
ldconfig
/etc/ld.so.cache
ldconfig
每当加载新程序时,动态加载器都会使用此缓存来加快查找所需库的速度。
如果您手动添加或删除系统库目录中的符号链接,您很可能必须ldconfig
随后以 root 身份运行才能使系统刷新缓存,从而使您的更改生效。如果不运行该命令,动态加载器将不知道库路径已更改,并且会愉快地继续使用旧缓存中的库路径。
虽然上面本质上是查找库的基本机制,但可以通过使用LD_LIBRARY_PATH
(= "首先检查这些库目录") 或LD_PRELOAD
(= "总是首先加载这个库)环境变量。
还可以使用名为DT_RPATH
(已弃用)或 的节属性将库路径信息嵌入到程序二进制文件本身中DT_RUNPATH
。这些也将覆盖缓存机制,但据我所知,它们的使用相当不寻常,恰恰因为当您需要一个程序在不再是一个系统/环境中工作时,它往往会导致像原始问题一样的问题精确的程序所针对的系统的匹配。