我对Linux处理环境变量如何传递给execve()有疑问:
execve()的概要: int execve(const char * filename,char * const argv [],char * const envp []);
在调用execve()之前,我们从当前进程的内存映射中分配用于保存envs / args的内存。但是在execve()之后,调用进程的所有text / data / bss / stack都被新程序覆盖,并且不保留旧进程的所有内存映射(包括传递的envs / args的内存)。 / p>
对于新程序,在哪里阅读envs / args?内核是否复制了传递的envs / args 并将其放在新的内存映射或其他一些技巧上?
答案 0 :(得分:9)
是
当进程调用exec
时,内核会复制整个argv
和envp
数组。然后,这些被复制到新的过程映像中 - 特别是,当程序开始运行时,它的堆栈看起来像:
NULL
...
envp[1]
envp[0]
NULL
argv[argc-1]
...
argv[1]
argv[0]
argc
_start
中的Glibc启动代码将此按摩到正确的形式以调用main
。
(有关更多详细信息,旧进程的副本在linux/fs/exec.c
中完成,新进程的副本在linux/fs/binfmt_elf.c
中完成,程序启动在特定于体系结构的代码中完成,例如glibc/sysdeps/i386/start.S
,glibc/sysdeps/x86_64/start.S
或glibc/ports/sysdeps/arm/start.S
,仅用于启动__libc_start_main
的{{3}}中的main
。)