execve()

execve()

2024 南京大学《操作系统:设计与实现》
execve()

下一个问题:如何运行可执行程序?

int execve(const char *filename,
           char * const argv[], char * const envp[]);

UNIX 的答案: execve (重置状态机)

  • 将当前进程重置成一个可执行文件描述状态机的初始状态

execve 行为

  • 执行名为 filename 的程序
  • 允许对新状态机设置参数 argv (v) 和环境变量 envp (e)
    • 刚好对应了 main() 的参数!
  • execve 是唯一能够 “执行程序” 的系统调用
    • 因此也是一切进程 strace 的第一个系统调用
2024 南京大学《操作系统:设计与实现》
execve()

fork() + execve()

UNIX 中实现 “创建新状态机” 的方式

  • Spawn = fork + execve
int pid = fork();
if (pid == -1) {
    perror("fork"); goto fail;
} else if (pid == 0) {
    // Child
    execve(...);
    perror("execve"); goto fail;
} else {
    // Parent
    ...
}
2024 南京大学《操作系统:设计与实现》
execve()

环境变量

“应用程序执行的环境”

  • 使用 env 命令查看
    • PATH: 可执行文件搜索路径
    • PWD: 当前路径
    • HOME: home 目录
    • DISPLAY: 图形输出
    • PS1: shell 的提示符
  • export: 告诉 shell 在创建子进程时设置环境变量
    • 小技巧:export ARCH=x86_64-qemuexport ARCH=native
2024 南京大学《操作系统:设计与实现》
execve()

环境变量:PATH

可执行文件搜索路径

  • 还记得 gcc 的 strace 结果吗?
[pid 28369] execve("/usr/local/sbin/as", ["as", "--64", ...
[pid 28369] execve("/usr/local/bin/as", ["as", "--64", ...
[pid 28369] execve("/usr/sbin/as", ["as", "--64", ...
[pid 28369] execve("/usr/bin/as", ["as", "--64", ...
  • 这个搜索顺序恰好是 PATH 里指定的顺序
$ PATH="" /usr/bin/gcc a.c
gcc: error trying to exec 'as': execvp: No such file or directory
$ PATH="/usr/bin/" gcc a.c

计算机系统里没有魔法。机器永远是对的。

2024 南京大学《操作系统:设计与实现》