Я только начинаю работать в операционных системах, и у меня есть это задание, в котором я не совсем понимаю ответ, необходимый для решения проблемы. В настоящее время я запускаю этот код в Ubuntu 16.04.5 LTS, в VirtualBox в MacOS.
Моя задача заключается в следующем: для строк, помеченных как LINE 4-LINE 8 в программе на C, сопоставьте их с системными вызовами из strace, объяснив, какие системные вызовы, по вашему мнению, происходят из какой строки программы.Попытайтесь объяснить для LINE 4-8, почему вы выполняете эти системные вызовы в трассировке.Чтобы упростить проблему, вы можете игнорировать следующие системные вызовы: brk, readlink, access, fstat, lseek
.
Вот код для отслеживаемой программы.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
void do_cleanup(void)
{
printf("do cleanup\n");
}
int main(int argc, char *argv[])
{
int pid; // you can use these variables
char buf[100];
atexit(do_cleanup); // LINE 1
setvbuf(stdout, 0, _IOLBF, 0); // LINE 2
// setvbuf(stdout, 0, _IOFBF, 0); // LINE 3
printf("Enter Name? "); // LINE 4
pid = getpid(); // LINE 5
scanf("%s", buf); // LINE 6
printf("Hello %s\n", buf); // LINE 7
printf(" your PID = %d\n", pid); // LINE 8
exit(EXIT_SUCCESS); // LINE 9
//_exit(EXIT_SUCCESS); // LINE 10
}
Запустив эти команды терминала
gcc -static -o hello hello.c
strace ./hello 2>strace-output.txt >hello-output.txt
Это то, что я получаю в strace
execve("./lab2-hello", ["./lab2-hello"], [/* 66 vars */]) = 0
uname({sysname="Linux", nodename="trial-VirtualBox", ...}) = 0
brk(NULL) = 0x1d1b000
brk(0x1d1c1c0) = 0x1d1c1c0
arch_prctl(ARCH_SET_FS, 0x1d1b880) = 0
readlink("/proc/self/exe", "/home/student/Desktop/hello"..., 4096) = 37
brk(0x1d3d1c0) = 0x1d3d1c0
brk(0x1d3e000) = 0x1d3e000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
getpid() = 2407
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 17), ...}) = 0
write(1, "Enter Name? ", 12) = 12
read(0, "2\n", 1024) = 2
write(1, "Hello 2\n", 8) = 8
write(1, " your PID = 2407\n", 17) = 17
write(1, "do cleanup\n", 11) = 11
lseek(0, -1, SEEK_CUR) = -1 ESPIPE (Illegal seek)
exit_group(0) = ?
+++ exited with 0 +++
Я думаю, что соответствия для строк с 4 по 8 таковы, с комментариями, содержащими системные вызовы
printf("Enter Name? ");// write(1, "Enter Name? ", 12) = 12
pid = getpid(); // getpid() = 2407
scanf("%s", buf); // read(0, "2\n", 1024) = 2
printf("Hello %s\n", buf);// write(1, "Hello 2\n", 8) = 8
printf(" your PID = %d\n", pid); // write(1, " your PID = 2407\n", 17) = 17
Однако при попытке прочитать справочные страницы команды виз этих соответствующих строк я понимаю, что многие из этих строк даже не являются системными вызовами, поскольку они встречаются в Руководстве по общим командам, когда я их печатаю в MacOS.Кто-нибудь знает, ошиблась ли моя идентификация?
Обновление:
Я понимаю, что в разных ядрах есть разные страницы руководства, и, зная, что man 2 write
существует, чтоэто еще один способ идентификации системных вызовов.Тем не менее, я до сих пор не понимаю, что на самом деле происходит под капотом через вызовы функций C, поскольку я вижу его только как язык программирования C, просто предоставляющий некоторые функции, которые вызывают соответствующий системный вызов под капотом.