Откуда берутся системные вызовы после execve in strace? И что они делают? - PullRequest
0 голосов
/ 31 марта 2020

В настоящее время я пишу программу, которая отслеживает системные вызовы процессов, и мне нужно больше знать об основных механизмах запуска процессов.

Вот runner.c:

>cat runner.c
#include "headers.h"
#include "helpers.h"

int main(int argc, char const *argv[])
{
        printf("Hello World\n");
        execlp("echo", "echo", "Runner", (char*)NULL);
        return 0;
}

Если я сделаю strace runner, первый вызов - это execve, который запускает программу, но откуда поступают все вызовы между execve и фактическое write, которое печатает Hello World?

>strace runner
execve("/media/sf_19-20/6CCS3PRJ/MVEE/c playground/runner", ["runner"], 0x7ffc61503c40 /* 42 vars */) = 0
brk(NULL)                               = 0x556111e53000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=79994, ...}) = 0
mmap(NULL, 79994, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcdf2470000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320l\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1820104, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcdf24b3000
mmap(NULL, 1832568, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fcdf22b0000
mprotect(0x7fcdf22d5000, 1642496, PROT_NONE) = 0
mmap(0x7fcdf22d5000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fcdf22d5000
mmap(0x7fcdf241c000, 299008, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16c000) = 0x7fcdf241c000
mmap(0x7fcdf2466000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fcdf2466000
mmap(0x7fcdf246c000, 13944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fcdf246c000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fcdf24b4500) = 0
mprotect(0x7fcdf2466000, 12288, PROT_READ) = 0
mprotect(0x556110910000, 4096, PROT_READ) = 0
mprotect(0x7fcdf24af000, 4096, PROT_READ) = 0
munmap(0x7fcdf2470000, 79994)           = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0), ...}) = 0
brk(NULL)                               = 0x556111e53000
brk(0x556111e74000)                     = 0x556111e74000
write(1, "Hello World\n", 12Hello World
)           = 12
execve("echo", ["echo", "Runner"], 0x7ffcd1a7f358 /* 42 vars */) = -1 ENOENT (No such file or directory)
execve("/usr/local/sbin/echo", ["echo", "Runner"], 0x7ffcd1a7f358 /* 42 vars */) = -1 ENOENT (No such file or directory)
execve("/usr/local/bin/echo", ["echo", "Runner"], 0x7ffcd1a7f358 /* 42 vars */) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/echo", ["echo", "Runner"], 0x7ffcd1a7f358 /* 42 vars */) = -1 ENOENT (No such file or directory)
execve("/usr/bin/echo", ["echo", "Runner"], 0x7ffcd1a7f358 /* 42 vars */) = 0
brk(NULL)                               = 0x5589c0f4e000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=79994, ...}) = 0
mmap(NULL, 79994, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b1f0000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320l\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1820104, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd49b237000
mmap(NULL, 1832568, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd49b030000
mprotect(0x7fd49b055000, 1642496, PROT_NONE) = 0
mmap(0x7fd49b055000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x25000) = 0x7fd49b055000
mmap(0x7fd49b19c000, 299008, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16c000) = 0x7fd49b19c000
mmap(0x7fd49b1e6000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fd49b1e6000
mmap(0x7fd49b1ec000, 13944, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd49b1ec000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fd49b238580) = 0
mprotect(0x7fd49b1e6000, 12288, PROT_READ) = 0
mprotect(0x5589bf871000, 4096, PROT_READ) = 0
mprotect(0x7fd49b22f000, 4096, PROT_READ) = 0
munmap(0x7fd49b1f0000, 79994)           = 0
brk(NULL)                               = 0x5589c0f4e000
brk(0x5589c0f6f000)                     = 0x5589c0f6f000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2995
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=368, ...}) = 0
mmap(NULL, 368, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b200000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26402, ...}) = 0
mmap(NULL, 26402, PROT_READ, MAP_SHARED, 3, 0) = 0x7fd49b1f8000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_MEASUREMENT", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=23, ...}) = 0
mmap(NULL, 23, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b1f0000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_TELEPHONE", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=59, ...}) = 0
mmap(NULL, 59, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b028000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_ADDRESS", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=167, ...}) = 0
mmap(NULL, 167, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b020000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_NAME", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=77, ...}) = 0
mmap(NULL, 77, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b018000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_PAPER", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=34, ...}) = 0
mmap(NULL, 34, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b010000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_MESSAGES", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=57, ...}) = 0
mmap(NULL, 57, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b008000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_MONETARY", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=286, ...}) = 0
mmap(NULL, 286, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49b000000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_COLLATE", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2586242, ...}) = 0
mmap(NULL, 2586242, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49ad88000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_TIME", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3284, ...}) = 0
mmap(NULL, 3284, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49ad80000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=54, ...}) = 0
mmap(NULL, 54, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49ad78000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/locale/en_US.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=337024, ...}) = 0
mmap(NULL, 337024, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fd49ad20000
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(0x88, 0), ...}) = 0
write(1, "Runner\n", 7Runner
)                 = 7
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Я знаю, что execve настраивает всю память для нового процесса и тому подобное (хотя я еще не знаю всех особенностей ), но где находится код, который выполняет эти системные вызовы после запуска execve? Я хотел бы увидеть исходный код.

Точно такие же вызовы делаются и после второго execve. Я предполагаю, что ядро ​​загружает этот код в память процесса и запускается после возврата вызова.

И что именно делает этот код?

Спасибо.

...