20

LD_PRELOAD_PATH 和 LD_LIBRARY_PATH 有什么区别?

我了解它们的作用,但不了解它们之间的区别。

来自 http://en.wikipedia.org/wiki/Dynamic_linker

可以影响动态链接器在程序执行或程序链接期间修改其行为。这方面的示例可以在各种类 Unix 系统的运行时链接器手册页中看到。此行为的典型修改是使用 LD_LIBRARY_PATH 和 LD_PRELOAD 环境变量。这些变量分别通过在备用位置搜索共享库以及通过强制加载和链接原本不会存在的库来调整运行时链接过程。

特别是,我对同时具有 LD_PRELOAD_PATH 和 LD_LIBRARY_PATH 的 Linux 中的差异感兴趣:

https://linuxgazette.net/issue48/tag/48.html

更新:这篇 1999 Linux Gazette 文章的作者在他 2013 年的评论中指出,公认的答案是 LD_PRELOAD_PATH 实际上并不存在。

4

2 回答 2

28

LD_PRELOAD(not LD_PRELOAD_PATH) 是要在任何其他库之前加载的特定库 ( files ) 的列表,无论程序是否需要。LD_LIBRARY_PATH是在加载本来会加载的库时要搜索的目录列表。在 linux 上,您可以阅读man ld.so有关这些和其他影响动态链接器的环境变量的更多信息。

于 2013-02-05T19:20:43.910 回答
5

LD_PRELOAD 更强大

最重要的区别是 LD_PRELOAD 可以替换静态链接到二进制文件中的函数。

例子

如果您发现 LD_PRELOAD 对您有用,但 LD_LIBRARY_PATH 神秘地不起作用,那么几乎可以肯定,这就是原因。

例如,我正在调试GNU Readlinebash起初我很困惑为什么我修改后的 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 无论如何都会加载库,允许库覆盖甚至是静态链接的函数。

于 2021-08-02T05:07:11.573 回答