execve()和环境变量 [英] execve() and environment variables
问题描述
我对Linux如何处理传递给execve()的环境变量有疑问:
execve()的简介: int execve(const char *文件名,char * const argv [],char * const envp []);
在调用execve()之前,我们从当前进程的内存映射中分配用于容纳envs/args的内存.但是在execve()之后,调用程序的所有文本/数据/bss/堆栈都会被新程序覆盖,并且旧进程的所有内存映射都不会保留(包括传递的envs/args的内存). /p>
对于新程序,在哪里读取envs/args?内核是否对传递的envs/args进行复制,并将其放置到新的内存映射中,或者其他一些技巧?
是.
当进程调用exec
时,内核将复制整个argv
和envp
数组.然后,将它们复制到新的过程映像中-值得注意的是,当程序开始运行时,其堆栈如下所示:
NULL
...
envp[1]
envp[0]
NULL
argv[argc-1]
...
argv[1]
argv[0]
argc
_start
中的Glibc启动代码将其压缩为适当的形式以调用main
.
(有关更多详细信息,旧过程的副本在 linux/fs/binfmt_elf.c
,程序启动为用特定于体系结构的代码完成,例如 glibc/sysdeps/i386/start.S
, glibc/ports/sysdeps/arm/start.S
,它的存在只是为了开始glibc/csu/libc-start.c
会启动main
.)
I've got a question with how Linux process the environment varibales passed to execve():
Synoposis for execve(): int execve(const char *filename, char *const argv[], char *const envp[]);
Before calling execve(), we allocate the memory for holding envs/args from current process's memory mapping. But after execve(), all the text/data/bss/stack of the calling process are overwriten by the new program, and all the memory mappings of the old process are not preserved (including the memory for passed envs/args).
For the new program, where to read the envs/args? Does the kernel make a copy of the passed envs/args and placed it onto the new memory mapping, or some other tricks?
Yes.
When a process calls exec
, the kernel copies the entire argv
and envp
arrays. Then, these are copied into the new process image -- notably, when the program starts running, its stack looks like:
NULL
...
envp[1]
envp[0]
NULL
argv[argc-1]
...
argv[1]
argv[0]
argc
The Glibc startup code in _start
massages this into the proper form to invoke main
.
(For more details, the copy from the old process is done in linux/fs/exec.c
, the copy to the new process is done in linux/fs/binfmt_elf.c
, and program startup is done in architecture-specific code such as glibc/sysdeps/i386/start.S
, glibc/sysdeps/x86_64/start.S
, or glibc/ports/sysdeps/arm/start.S
, which exist just to kick off into __libc_start_main
in glibc/csu/libc-start.c
which launches main
.)
这篇关于execve()和环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!