Linux在动态链接库
加载过程中,会先读取LD_PRELOAD
环境变量,并将读取到的动态链接库文件
进行预加载
介绍
用途
工作原理
/usr/lib/x86_64-linux-gnu/ld-2.31.so
是一个 动态链接器(dynamic linker)
,它的主要作用是在程序运行时动态地 加载
和 链接
共享库(shared libraries)
- 通过环境变量
LD_PRELOAD
加载共享库 - 当程序需要调用某个
符号
(例如函数)时,系统会先在程序自身的符号表中查找。如果找不到,系统会在 LD_PRELOAD
指定的共享库中查找,如果在 LD_PRELOAD
指定的共享库中找到了该符号,则使用代码中的 符号
加载顺序
- Linux中,通过
/usr/lib/x86_64-linux-gnu/ld-2.31.so
动态链接库加载顺序:
LD_PRELOAD -> LD_LIBRARY_PATH -> /etc/ld.so.cache -> /lib -> /usr/lib
配置文件
/etc/ld.so.conf
指向 include /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf.d/
/etc/ld.so.cache
示例
自动生成随机数示例
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
int i;
srand(time(NULL));
for(i=0; i<5; i++){
printf("%d\n", rand() % 100);
}
return 0;
}
# 编译 rund
$ gcc -o rund rund.c
# 运行
$ ./rund
8
30
27
69
48
- 创建
myrand.c
并编译为动态链接库 libmyrand.so
myrand.c
#include<stdio.h>
int rand()
{
return 99;
}
编译:
-shared
生成共享库格式-fPIC
用于编译阶段,编译器会产生与 位置无关(Position-Independent)
的动态库
gcc -o libmyrand.so -shared -fPIC myrand.c
- 运行,结果都是 99,实际为
libmyrand.so
的执行结果
LD_PRELOAD=$PWD/libmyrand.so ./rund
99
99
99
99
99
# 默认
$ ldd ./rund
linux-vdso.so.1 (0x00007ffd863b6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fba93ddf000)
/lib64/ld-linux-x86-64.so.2 (0x00007fba93fec000)
# LD_PRELOAD,可以看到 /root/libmyrand.so 的加载
$ LD_PRELOAD=$PWD/libmyrand.so ldd ./rund
linux-vdso.so.1 (0x00007ffd5eff0000)
/root/libmyrand.so (0x00007ffa23a05000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffa237ff000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffa23a11000)
- 删除环境变量
- 方法一:
export -n LD_PRELOAD=$PWD/libmyrand.so
,且 echo $LD_PRELOAD
其值不变,但已经不生效了 - 方法二:
unset LD_PRELOAD
扩展