swe*_*ion 2 bash process environment-variables elf linux-kernel
不久前,我正在使用 GDB 探索一个简单的 C 程序的 ELF 二进制文件。我看到我printenv
在终端中运行时打印的环境变量也出现在我在该终端中运行的 C 程序二进制文件的堆栈顶部。
Bash 如何实际执行程序,同时所有环境变量也被添加到新进程的堆栈中?简而言之,当我运行这样的程序时会发生什么:
./myprogram
使用execve
系统调用执行 Linux 程序。execve
具有以下签名:
int execve(const char *filename, char *const argv[], char *const envp[]);
Run Code Online (Sandbox Code Playgroud)
最后一个参数envp
用于将环境作为字符串数组传递给进程,每个字符串的形式为 key=value。按照惯例,相同的环境从一个进程传递到另一个进程,除非调用进程对其进行一些更改。内核安排新程序接收堆栈上的环境,与传递程序参数的方式相同。
库函数execl
、execlp
、execv
和execvp
不接受envp
参数(但execle
和execvpe
函数接受)。这些函数从environ
调用过程中的全局变量中获取环境。这样一个程序使用该execle
函数启动另一个程序就不必担心传递环境,但库函数会在“幕后”自动完成。
所有提到的库函数最终都会调用execve
系统调用,并在envp
参数中传递环境。