LD_PRELOAD
设置为共享对象的路径,那么该文件将在任何其他库(包括C运行时库libc.so
)之前被加载。所以要使用您特殊的malloc()
实现运行ls
,请执行以下操作:$ LD_PRELOAD=/path/to/my/malloc.so /bin/ls
LD_PRELOAD
。原因是它是一个环境变量,会被子进程继承 - 这些子进程可能具有与父进程不同的工作目录。因此,任何相对路径都无法定位要预加载的库。 - Frerich Raabe您可以通过创建一个包含相同符号的库,并在LD_PRELOAD
中指定该库,来覆盖库中的符号。
有些人使用它来指定非标准位置的库,但是对于这个目的,LD_LIBRARY_PATH
更好。
正如很多人提到的那样,可以使用LD_PRELOAD
来预加载库。另外,您可以使用ldd
命令检查是否可用该设置。
例:假设您需要预加载自己的libselinux.so.1
。
libselinux.so.1
。> ldd /bin/ls
...
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3927b1d000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f3927914000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f392754f000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f3927311000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f392710c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3927d65000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3926f07000)
因此,请设置您的预加载环境:
export LD_PRELOAD=/home/patric/libselinux.so.1
再检查一遍你的图书馆:
>ldd /bin/ls
...
libselinux.so.1 =>
/home/patric/libselinux.so.1 (0x00007fb9245d8000)
...
LD_PRELOAD
可以给库设置优先级。malloc
和free
的库,并通过使用LD_PRELOAD
来加载这些库,使其优先于标准库执行malloc
和free
。calloc
那会怎样呢?这不会搞乱一切吗? - Janus Troelsenmalloc
和free
是专门设计用来实现这一点的,标准的calloc
函数也能调用你导入的malloc
函数。不要尝试使用其他函数来实现这个目的,效果可能不好。翻译:原来在glibc库中,malloc
和free
函数被特别设计成可以实现这个功能,而标准的calloc
函数会调用你所导入的malloc
函数。但不要尝试使用其他函数来实现这个目的,效果可能不佳。 - JoshuaLD_PRELOAD
是一种列出具有覆盖标准库函数的共享库的方法,与 /etc/ld.so.preload
类似。这些功能由加载器 /lib/ld-linux.so
实现。如果您只想覆盖一些选择的功能,可以创建一个覆盖对象文件并设置 LD_PRELOAD
;该对象文件中的函数将仅覆盖那些函数,而保留其他函数不变。
有关共享库的更多信息,请访问http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
mylib.so
导出到环境变量中:$ export LD_PRELOAD=/path/mylib.so
$ ./mybin
要禁用它:
$ unset LD_PRELOAD
unset
和 export VAR=
并不完全相同,使用 unset
更为合适。 - Michał Leon以下是关于预加载的详细博客文章:
$export LD_PRELOAD=/path/lib
来预加载lib。这甚至可以在程序中使用。"Original Answer"翻译成"最初的回答"。LD_PRELOAD
路径,您可以强制应用程序加载器加载提供的共享对象,而不是默认提供的对象。