追踪一个main.c的周期

使用strace工具追踪main.c的gcc编译过程及a.out的执行过程

追踪gcc编译过程

1
strace -o /dev/stdout gcc hello.c 2>&1 | vim -

将strace追踪信息利用|(管道) 传递给vim, 这边要注意的是strace的输出是直接发送到标准错误输出stderr, 而不是标准输出stdout, 所以用-o dev/stdout将输出写到标准输出中, 2>&1是将标准错误stderr(文件描述符2)重定向到标准输出stdout(文件描述符1)中, 详情见此处.

那么我们可以得到这些信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
execve("/usr/bin/gcc", ["gcc", "hello.c"], 0x7ffde6f6a6e8 /* 57 vars */) = 0
brk(NULL) = 0x198a000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1a6461f000
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
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=94102, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 94102, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1a64608000
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\20t\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=1922136, ...}, AT_EMPTY_PATH) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
mmap(NULL, 1970000, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f1a64427000
mmap(0x7f1a6444d000, 1396736, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f1a6444d000
mmap(0x7f1a645a2000, 339968, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17b000) = 0x7f1a645a2000
mmap(0x7f1a645f5000, 24571段:程序启动和初始化(行1-15
解释:这一段描述了gcc编译器启动的初始步骤。execve系统调用用于执行gcc程序,后续的brk和mmap调用进行内存分配和管理,为程序的运行准备必要的资源。接着,通过openat和read系统调用,程序尝试访问和读取系统的动态链接器配置(/etc/ld.so.cache)和标准C库(libc.so.6),这是程序运行前的必要准备,以确保能够正确链接到所需的共享库。
2段:环境设置(行16-27
解释:程序继续进行环境设置,包括通过mmap为特定的数据结构分配更多内存,设置线程特定的数据(如arch_prctl调用设定线程的FS寄存器),并进行一些内存保护设置(mprotect调用)。这一部分的操作主要关注于为程序的执行和系统调用提供必要的环境配置。
3段:本地化和错误消息处理(行28-49
解释:gcc尝试加载本地化支持文件,以便能够显示本地化的错误消息。通过一系列的openat调用搜索本地化文件,所有尝试均返回ENOENT(文件不存在),说明在指定的路径下没有找到相应的本地化文件。此外,ioctl调用的失败表明尝试获取终端属性未成功,这通常是因为gcc可能在没有终端的环境中运行(例如,脚本或其他自动化工具中)。
4段:编译前的准备(行50-95
解释:这段涉及到编译前的准备工作,包括对信号处理的设置(如rt_sigaction调用),以确保在编译过程中能够正确处理诸如中断(SIGINT)和挂起(SIGHUP)等信号。接着,gcc进行一系列的路径和文件检查,确认编译器组件和工具链的位置(如查找gcc,cc1,以及相关库文件的位置)。这些步骤确保了编译过程可以找到所有必要的编译器组件和工具。
5段:编译过程(行96-204
解释:这是实际编译过程的核心部分,涉及多个阶段,包括预处理、编译、汇编和链接。在这一段中,gcc生成了临时文件(如汇编代码文件),调用子进程(通过vfork和execve)来执行如cc1(gcc的编译器前端),汇编器(as),以及链接器(ld或collect2)。此外,通过pipe2和wait4等系统调用进行进程间通信和同步,确保编译过程按顺序进行。各种临时文件被创建和删除(unlink),是编译过程中间步骤的产物。
6段:清理和退出(行205-210
解释:在编译任务完成后,gcc进行清理工作,包括删除临时文件,并最终通过exit_group系统调用退出程序。这表示编译过程已经全部完成,所有资源被适当地释放,gcc以返回状态码0正常退出,标志着编译成功。, 0) = 0x7f1a645fb000
close(3) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1a64424000
arch_prctl(ARCH_SET_FS, 0x7f1a64424740) = 0
set_tid_address(0x7f1a64424a10) = 16201
set_robust_list(0x7f1a64424a20, 24) = 0
rseq(0x7f1a64425060, 0x20, 0, 0x53053053) = 0
mprotect(0x7f1a645f5000, 16384, PROT_READ) = 0
mprotect(0x539000, 12288, PROT_READ) = 0
mprotect(0x7f1a64651000, 8192, PROT_READ) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
munmap(0x7f1a64608000, 94102) = 0
getrandom("\xe0\xcb\x2e\x04\x26\xb5\x6a\x8e", 8, GRND_NONBLOCK) = 8
brk(NULL) = 0x198a000
brk(0x19ab000) = 0x19ab000
brk(0x19cd000) = 0x19cd000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=6209168, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 6209168, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1a63e00000
close(3) = 0
openat(AT_FDCWD, "/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=2996, ...}, AT_EMPTY_PATH) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2996
read(3, "", 4096) = 0
close(3) = 0
openat(AT_FDCWD, "/usr/share/locale/en_US.UTF-8/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US.utf8/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en_US/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.UTF-8/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en.utf8/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/en/LC_MESSAGES/gcc-12.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
ioctl(2, TCGETS, 0x7ffea2eb7580) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, TCGETS, 0x7ffea2eb7590) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(2, TCGETS, 0x7ffea2eb7580) = -1 ENOTTY (Inappropriate ioctl for device)
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[INT], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x4079b0, sa_mask=[INT], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_IGN, sa_mask=[INT], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, 8) = 0
rt_sigaction(SIGHUP, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGHUP, {sa_handler=0x4079b0, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_IGN, sa_mask=[HUP], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, 8) = 0
rt_sigaction(SIGTERM, {sa_handler=SIG_IGN, sa_mask=[TERM], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTERM, {sa_handler=0x4079b0, sa_mask=[TERM], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_IGN, sa_mask=[TERM], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x4079b0, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_IGN, sa_mask=[PIPE], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[CHLD], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f1a64463050}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_STACK, {rlim_cur=65536*1024, rlim_max=RLIM64_INFINITY}, NULL) = 0
access("/usr/local/bin/gcc", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/bin/gcc", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/gcc", {st_mode=S_IFREG|0755, st_size=1301496, ...}, 0) = 0
readlink("/usr", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/bin", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/bin/gcc", "gcc-12", 1023) = 6
readlink("/usr/bin/gcc-12", "x86_64-linux-gnu-gcc-12", 1023) = 23
readlink("/usr/bin/x86_64-linux-gnu-gcc-12", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
access("/usr/local/bin/gcc", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/bin/gcc", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/bin/gcc", {st_mode=S_IFREG|0755, st_size=1301496, ...}, 0) = 0
readlink("/usr", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/bin", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
readlink("/usr/bin/gcc", "gcc-12", 1023) = 6
readlink("/usr/bin/gcc-12", "x86_64-linux-gnu-gcc-12", 1023) = 23
readlink("/usr/bin/x86_64-linux-gnu-gcc-12", 0x7ffea2eb5f60, 1023) = -1 EINVAL (Invalid argument)
access("/usr/lib/gcc/x86_64-linux-gnu/12/", X_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/", X_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/", X_OK) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper", {st_mode=S_IFREG|0755, st_size=1180024, ...}, 0) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper", X_OK) = 0
access("/tmp", R_OK|W_OK|X_OK) = 0
newfstatat(AT_FDCWD, "/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=4096, ...}, 0) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2059, tv_nsec=553951022}) = 0
openat(AT_FDCWD, "/tmp/ccbdUzto.s", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
close(3) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/cc1", {st_mode=S_IFREG|0755, st_size=33342568, ...}, 0) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/cc1", X_OK) = 0
pipe2([3, 4], O_CLOEXEC) = 0
vfork() = 16202
close(4) = 0
read(3, "", 16) = 0
close(3) = 0
wait4(16202, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16202
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=16202, si_uid=1000, si_status=0, si_utime=1 /* 0.01 s */, si_stime=1 /* 0.01 s */} ---
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2059, tv_nsec=601463828}) = 0
openat(AT_FDCWD, "/tmp/ccvZGP4P.o", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
close(3) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/12/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/12/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu-as", 0x7ffea2eb7230, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/as", 0x7ffea2eb72f0, 0) = -1 ENOENT (No such file or directory)
pipe2([3, 4], O_CLOEXEC) = 0
vfork() = 16203
close(4) = 0
read(3, "", 16) = 0
close(3) = 0
wait4(16203, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16203
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=16203, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/collect2", {st_mode=S_IFREG|0755, st_size=639192, ...}, 0) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/collect2", X_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so", R_OK) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/12/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/bin/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/12/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/lib/../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/.", 0x7ffea2eb7420, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
clock_gettime(CLOCK_MONOTONIC, {tv_sec=2059, tv_nsec=611785599}) = 0
openat(AT_FDCWD, "/tmp/ccmo4bus.res", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
close(3) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/Scrt1.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/Scrt1.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/Scrt1.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib/Scrt1.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/12/Scrt1.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o", R_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/crti.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/crti.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/crti.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib/crti.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/12/crti.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o", R_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o", R_OK) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/12/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/lib/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/lib/../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/12/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/.", {st_mode=S_IFDIR|0755, st_size=126976, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/../lib/.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/.", 0x7ffea2eb6640, 0) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/../../../.", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o", R_OK) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/crtn.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/12/crtn.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/crtn.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib/crtn.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/12/crtn.o", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o", R_OK) = 0
newfstatat(AT_FDCWD, "/usr/lib/gcc/x86_64-linux-gnu/12/collect2", {st_mode=S_IFREG|0755, st_size=639192, ...}, 0) = 0
access("/usr/lib/gcc/x86_64-linux-gnu/12/collect2", X_OK) = 0
pipe2([3, 4], O_CLOEXEC) = 0
vfork() = 16204
close(4) = 0
read(3, "", 16) = 0
close(3) = 0
wait4(16204, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16204
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=16204, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
newfstatat(AT_FDCWD, "/tmp/ccmo4bus.res", {st_mode=S_IFREG|0600, st_size=0, ...}, 0) = 0
unlink("/tmp/ccmo4bus.res") = 0
newfstatat(AT_FDCWD, "/tmp/ccvZGP4P.o", {st_mode=S_IFREG|0600, st_size=1384, ...}, 0) = 0
unlink("/tmp/ccvZGP4P.o") = 0
newfstatat(AT_FDCWD, "/tmp/ccbdUzto.s", {st_mode=S_IFREG|0600, st_size=541, ...}, 0) = 0
unlink("/tmp/ccbdUzto.s") = 0
exit_group(0) = ?
+++ exited with 0 +++

信息非常乱, 但是我先列出每个函数的作用(生成自gpt):

系统调用解释

以下是对提供的strace输出中每行开头的系统调用或相关函数的解释:

  • execve: 执行一个程序,是程序运行的起点。替换当前进程的映像、数据和堆栈等为新程序的映像和数据,新程序从main开始执行。

  • brk: 调整数据段末尾的地址,用于增加或减少数据段的大小,即动态分配或释放内存。

  • mmap: 创建一个新的映射(mapping)在调用进程的虚拟地址空间,用于分配内存或将文件直接映射到内存中。

  • access: 检查调用进程是否可以访问指定的文件路径,用于检查文件是否存在及其读写权限。

  • openat: 打开一个文件或目录,AT_FDCWD表示相对于当前工作目录的路径。

  • newfstatat: 获取文件的状态信息,如大小、权限、最后修改时间等。

  • close: 关闭一个文件描述符,释放其所占用的资源。

  • read: 从文件描述符指向的文件中读取数据。

  • pread64: 从文件描述符指向的文件中读取数据,可以指定从哪个位置开始读取,不改变文件的当前偏移量。

  • arch_prctl: 设置特定架构的进程或线程的状态,如线程局部存储区域。

  • set_tid_address: 设置线程ID的存储地址,用于内核在特定事件(如线程退出)时更新信息。

  • set_robust_list: 设置线程的鲁棒列表(robust list),用于处理锁的死亡解锁。

  • rseq: 重启序列系统调用,用于在用户空间实现快速的锁和同步机制。

  • mprotect: 改变一块内存区域的保护属性,如设置为只读。

  • ioctl: 对设备特定的输入/输出操作进行控制。

  • rt_sigaction: 检查或修改与特定信号相关联的处理动作。

  • prlimit64: 获取或设置进程资源限制,如最大可用内存、最大打开文件数等。

  • getrandom: 从内核的随机数生成器获取随机数。

  • unlink: 删除一个文件的链接,如果是文件的最后一个链接,并且没有进程打开该文件,则文件被删除。

  • exit_group: 终止调用进程所在的整个进程组,通常在程序结束时调用。

下面对追踪信息进行基本解释:

GCC编译器执行过程分析

第1段:程序启动和初始化(行1-15)

这一段描述了gcc编译器启动的初始步骤。execve系统调用用于执行gcc程序,后续的brkmmap调用进行内存分配和管理,为程序的运行准备必要的资源。接着,通过openatread系统调用,程序尝试访问和读取系统的动态链接器配置(/etc/ld.so.cache)和标准C库(libc.so.6),这是程序运行前的必要准备,以确保能够正确链接到所需的共享库。

第2段:环境设置(行16-27)

程序继续进行环境设置,包括通过mmap为特定的数据结构分配更多内存,设置线程特定的数据(如arch_prctl调用设定线程的FS寄存器),并进行一些内存保护设置(mprotect调用)。这一部分的操作主要关注于为程序的执行和系统调用提供必要的环境配置。

第3段:本地化和错误消息处理(行28-49)

gcc尝试加载本地化支持文件,以便能够显示本地化的错误消息。通过一系列的openat调用搜索本地化文件,所有尝试均返回ENOENT(文件不存在),说明在指定的路径下没有找到相应的本地化文件。我没有下载本地化文件,所以这一步会加载失败,并且如果GCC未找到对应的.mo文件,它会回退到默认的(通常是英文)消息。此外,ioctl调用的失败表明尝试获取终端属性未成功,这通常是因为gcc可能在没有终端的环境中运行(例如,脚本或其他自动化工具中)。

本地化

本地化(Localization),通常简写为l10n(因为单词中”L”和”n”之间有10个字母),指的是将产品(如软件、文档、网站等)或内容调整以适应特定地区或语言的用户的过程。这不仅涉及到翻译文本内容,还包括符合当地文化、法律和需求的各种适应性调整。本地化的目标是为用户提供尽可能亲切和自然的使用体验,使产品看起来像是为特定的用户群体量身定做的。以下是本地化过程中常涉及的一些关键方面:

  1. 语言和文本翻译

将产品界面、帮助文档、用户手册等文本从一种语言翻译到另一种语言,确保语言的准确性和地道性。

  1. 文化适应性

考虑和适应目标地区的文化习俗和预期,如颜色、图标的文化含义,以及布局方式等,以避免文化冲突或误解。

  1. 法律和规范遵循

确保产品符合目标地区的法律法规和业务习惯,包括隐私政策、版权信息、数据保护规则等。

  1. 技术适应性

适应目标地区的技术标准和习惯,如日期和时间格式、数字格式(小数点和千位分隔符)、度量单位(公制或英制)、货币单位等。

  1. 排版和界面调整

根据语言的阅读方向(如从左到右或从右到左)调整用户界面的布局和排版,确保界面元素的适当展示和用户交互的便利性。
通过本地化,可以大大增强用户体验,提高产品的市场接受度和用户满意度。对于全球市场的软件开发者而言,本地化是一个重要的步骤,有助于将产品推广到不同语言和文化背景的用户中。

第4段:编译前的准备(行50-95)

这段涉及到编译前的准备工作,包括对信号处理的设置(如rt_sigaction调用),以确保在编译过程中能够正确处理诸如中断(SIGINT)和挂起(SIGHUP)等信号。接着,gcc进行一系列的路径和文件检查,确认编译器组件和工具链的位置(如查找gcc,cc1,以及相关库文件的位置)。这些步骤确保了编译过程可以找到所有必要的编译器组件和工具。

第5段:编译过程(行96-204)

这是实际编译过程的核心部分,涉及多个阶段,包括预处理、编译、汇编和链接。在这一段中,gcc生成了临时文件(如汇编代码文件),调用子进程(通过vforkexecve)来执行如cc1(gcc的编译器前端),汇编器(as),以及链接器(ld或collect2)。此外,通过pipe2wait4等系统调用进行进程间通信和同步,确保编译过程按顺序进行。各种临时文件被创建和删除(unlink),是编译过程中间步骤的产物。

第6段:清理和退出(行205-210)

在编译任务完成后,gcc进行清理工作,包括删除临时文件,并最终通过exit_group系统调用退出程序。这表示编译过程已经全部完成,所有资源被适当地释放,gcc以返回状态码0正常退出,标志着编译成功。