LD_PRELOAD_PATH和LD_LIBRARY_PATH之间有什么区别?

时间:2013-02-05 19:17:39

标签: linker shared-libraries

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的差异:

http://linuxgazette.berlios.de/issue48/tag/48.html

2 个答案:

答案 0 :(得分:15)

LD_PRELOAD(不是LD_PRELOAD_PATH)是要在任何其他库之前加载的特定库(文件)的列表,无论程序是否需要它。 LD_LIBRARY_PATH是一个目录的列表,用于在加载原本已加载的库时进行搜索。在linux上,您可以阅读man ld.so以获取有关影响动态链接器的这些和其他环境变量的更多信息。

答案 1 :(得分:0)

LD_PRELOAD 更强大

最重要的区别是 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 无论如何都会加载库,从而允许库覆盖甚至静态链接的函数。