本文主要介绍:Linux 下系统调用和 strace 工具概述;
公众号: 滑翔的纸飞机
当 Linux 上运行的应用程序/进程要使用 Linux 内核管理的资源时,如读取文件、创建进程等。应用程序进程向 Linux 内核发出系统调用,Linux 内核执行必要的操作,然后将控制权交还给调用程序。strace 工具提供了跟踪 Linux 系统调用的功能。
在 Linux 中创建文件时,我们只需运行一条命令,输入所需的文件名即可。看起来很简单,对吧?但在这个简单的任务下面,却涉及到许多系统调用。要想知道所有的系统调用,我们可以运行以下命令:
root@dev:~# strace touch test.txt
execve("/usr/bin/touch", ["touch", "test.txt"], 0x7fff904e9a98 /* 23 vars */) = 0
brk(NULL) = 0x55731c7a9000
... ...
执行上述命令后,我们将看到创建一个简单文件期间系统调用的大量信息。我们可以看到一个名为 “execve"的系统被调用,该系统调用将执行一个位于”/usr/bin/touch "目录下的程序。
要跟踪一个正在运行的进程所进行的系统调用,我们需要获取该进程的 PID。通过使用该特定进程的 PID,我们可以查看该进程进行的实时系统调用。让我们获取 "kube-proxy "进程的 PID:
root@dev:~# pidof kube-proxy
----------------------------------------------------------------
25166
现在,我们可以使用 PID 查看 kube-proxy 进程实时的系统调用:
root@dev:~# strace -p 25166
-------------------------------------------------------------------
strace: Process 25166 attached
epoll_pwait(4, [], 128, 0, NULL, 140720404847384) = 0
epoll_pwait(4, [], 128, 832, NULL, 140720404847448) = 0
epoll_pwait(4, [], 128, 0, NULL, 140720404847384) = 0
epoll_pwait(4, [], 128, 4999, NULL, 140720404847448) = 0
epoll_pwait(4, [], 128, 0, NULL, 140720404847384) = 0
epoll_pwait(4, [], 128, 4484, NULL, 140720404847448) = 0
getrandom("\x20\xa7\xb0\xd9\x16\x22\x76\x58", 8, 0) = 8
write(11, "\27\3\3\0\"Zl\25dan\2711i\361.K\215\343\207A>\327\5_xZ\370P:H\17"..., 39) = 39
.....
要查看一条命令的系统调用次数的完整摘要,请使用以下命令:
root@dev:~# strace -c touch test
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
37.20 0.000500 26 19 openat
21.58 0.000290 13 22 mmap
21.06 0.000283 12 22 close
15.03 0.000202 11 18 fstat
2.60 0.000035 11 3 read
1.56 0.000021 21 1 utimensat
0.97 0.000013 13 1 dup2
0.00 0.000000 0 3 mprotect
0.00 0.000000 0 1 munmap
0.00 0.000000 0 3 brk
0.00 0.000000 0 6 pread64
0.00 0.000000 0 1 1 access
0.00 0.000000 0 1 execve
0.00 0.000000 0 2 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.001344 103 2 total
要检查某些系统调用,请运行以下命令:
root@dev:~# strace -e trace=read touch test1.txt
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300A\2\0\0\0\0\0"..., 832) = 832
read(3, "# Locale name alias data base.\n#"..., 4096) = 2996
read(3, "", 4096) = 0
+++ exited with 0 +++
root@dev:~# strace -c -e trace=read,close touch test2.txt
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.000049 2 22 close
0.00 0.000000 0 3 read
------ ----------- ----------- --------- --------- ----------------
100.00 0.000049 25 total