何时以及如何创建进程控制块

sou*_*yar 5 c linux assembly

#include <stdio.h>

int main(void)
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

何时以及如何为上述程序创建进程控制块?

例如,在上述程序进入运行状态之前,内核必须为此进程分配一块pcb。

我在哪里可以找到对内核进行的各种启动系统调用,以便我可以将这些调用跟踪到内核中。

我在上面的程序上运行了一个 strace,但我无法得到它。

execve("./a.out", ["./a.out"], [/* 42 vars */]) = 0
brk(0)                                  = 0x9aaf000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or      directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78df000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=112037, ...}) = 0
mmap2(NULL, 112037, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb78c3000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220o\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1462852, ...}) = 0
mmap2(NULL, 1473032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x456000
mprotect(0x5b7000, 4096, PROT_NONE)     = 0
mmap2(0x5b8000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x161) = 0x5b8000
mmap2(0x5bb000, 10760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x5bb000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78c2000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb78c28d0,  limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1,   seg_not_present:0, useable:1}) = 0
mprotect(0x5b8000, 8192, PROT_READ)     = 0
mprotect(0x8049000, 4096, PROT_READ)    = 0
mprotect(0xa92000, 4096, PROT_READ)     = 0
munmap(0xb78c3000, 112037)              = 0
exit_group(0)                           = ?
Run Code Online (Sandbox Code Playgroud)

需要一些提示来期待......

Sti*_*tad 0

进程的创建发生在内核空间而不是用户空间,因此您在任何用户空间库中都找不到用于创建特定于进程的内容的代码。(您可以在用户空间库中找到 .so 文件加载器/运行时链接器等)

进程的实际创建发生在系统调用 fork() 或 clone() 内。这导致调用进程被分成两个,父进程和子进程。系统调用的返回值将告诉调用进程它们是哪一个。最常见的用法是子进程在 fork() 之后执行 exec() 系统调用。这会导致进程程序被使用调用者资源(文件描述符、环境、用户、组、当前工作目录等)的新可执行文件替换。

如果您跟踪执行 shell 脚本的 shell,则可以看到此操作。