LD_DEBUG 是什么?

基本用法

我第一次见到LD_DEBUG的使用,是下面这种方式(其实也是最常用的方式,我猜的):

1
$ LD_DEBUG=bindings ./hello

当时觉得很神奇,有点像魔法,不过经过一些思考,还是发现了一些端倪。根据一些
经验,猜测前面的LD_DEBUG=bindings可能是要在 shell 里定义变量,但又不同于
一般的定义形式,觉得可能是临时定义一个变量。于是写一个程序打印出环境变量看
一下,果然是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[], char *envp[])
{
int i;
extern char **environ;

/* print envp */
printf("%s\n", "envp:");
for (i=0; envp[i]; i++) {
printf(" envp[%d]: %s\n", i, envp[i]);
}

/* print environ, should be the same with envp */
printf("%s\n", "environ:");
for (i=0; environ[i]; i++) {
printf(" environ[%d]: %s\n", i, environ[i]);
}
return 0;
}

打印出来确实是有这个变量的,程序结束后环境变量中也没有这个项(可以使用
env命令打印出所有环境变量),确认是临时的变量。其实也可以在 shell 里直接
定义这个变量,但因为这个变量的存在会使动态链接器/加载器输出一些信息,所以不
推荐这么做。

LD_DEBUG影响了谁?

LD_DEBUG会影响动态链接器/加载器(dynamic linker/loader),即ld.so
ld-linux.so*的运行,完整的文档可以查看man ld.so。以下翻译一下[1]中的问
题答案:

LD_DEBUG在这里只是一个环境变量,且你把值libs赋给了它。这除了会把
LD_DEBUG添加到你运行的命令的环境里并不会有其他的用处。

当你运行一个动态链接的可执行文件,ld.so(8)须要首先进行运行时链接和符号
解析。动态链接器和其他任何程序一样都可以读取环境变量。链接器谈会读取
LD_DEBUG和其他一些环境变量,并根据它们来改变自己的行为。手册里有所有会
影响动态链接器行为的环境变量名称。

这个回答已经说得很清楚了。使用LD_DEBUG=help可以查看所有可以取得的值,其他
的一些变量名称还包括LD_ASSUME_KERNELLD_LIBRARY_PATHLD_PRELOAD
LD_ORIGIN_PATH等。

References

[1] how an expression which contains LD_DEBUG is processed?
[2] 在 Linux 下学习 C 语言有什么好处?
[3] man ld.so

0%