LD_PRELOAD_PATH和LD_LIBRARY_PATH之间有什么区别?
我明白他们做了什么,但不了解他们的不同之处。
从 http://en.wikipedia.org/wiki/Dynamic_linker
可以影响动态链接器修改其行为 在程序执行或程序链接期间。 可以在运行时链接器手册页中看到此示例 各种类Unix系统。典型的修改 这种行为是使用LD_LIBRARY_PATH和LD_PRELOAD 环境变量。这些变量调整运行时链接 通过在备用位置搜索共享库来进行处理 通过强制加载和链接原本不存在的库, 分别
我特别感兴趣的是Linux中存在LD_PRELOAD_PATH和LD_LIBRARY_PATH的差异:
答案 0 :(得分:15)
LD_PRELOAD
(不是LD_PRELOAD_PATH
)是要在任何其他库之前加载的特定库(文件)的列表,无论程序是否需要它。 LD_LIBRARY_PATH
是一个目录的列表,用于在加载原本已加载的库时进行搜索。在linux上,您可以阅读man ld.so
以获取有关影响动态链接器的这些和其他环境变量的更多信息。
答案 1 :(得分:0)
最重要的区别是 LD_PRELOAD 可以替换静态链接到二进制文件中的函数。
如果您发现 LD_PRELOAD 对您有用,但 LD_LIBRARY_PATH 莫名其妙地不起作用,那么几乎可以肯定,这就是原因。
例如,我在 bash
中调试 GNU Readline,起初很困惑为什么我修改后的 libreadline.so 加载的是 LD_PRELOAD 而不是 LD_LIBRARY_PATH。
$ LD_PRELOAD=shlib/libreadline.so bash -
(worked)
$ LD_LIBRARY_PATH=shlib/ bash -
(failed)
看看 ldd 命令,它列出了动态链接库的依赖关系,给出了答案:
$ ldd /bin/bash
linux-vdso.so.1
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
果然,libreadline 没有被列为共享库之一。因此,我机器上的 /bin/bash 必须在编译时与其自己的 libreadline 版本静态链接。 LD_LIBRARY_PATH 不起作用的原因是二进制文件从不要求动态链接器 (ld.so) 加载 libreadline。
另一方面,LD_PRELOAD 无论如何都会加载库,从而允许库覆盖甚至静态链接的函数。