4

我有一个关于 Linux 如何处理传递给 execve() 的环境变量的问题:

execve() 的概要: int execve(const char *filename, char *const argv[], char *const envp[]);

在调用 execve() 之前,我们从当前进程的内存映射中分配用于保存 envs/args 的内存。但是在 execve() 之后,调用进程的所有 text/data/bss/stack 都会被新程序覆盖,并且不会保留旧进程的所有内存映射(包括传递的 envs/args 的内存)。

对于新程序,在哪里读取 envs/args?内核是否会复制传递的 envs/args 并将其放置到新的内存映射中,或者其他一些技巧?

4

1 回答 1

9

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.)

于 2012-08-18T06:53:24.953 回答