一、strace的用途
strace 是最常用的跟踪进程系统调用的工具。
二、查看strace所属的包及安装
1. strace所属的包
[root@localhost system]# whereis strace strace: /usr/bin/strace /usr/share/man/man1/strace.1.gz [root@localhost system]# rpm -qf /usr/bin/strace strace-4.24-4.el7.x86_64
2. 如果找不到strace命令,可以使用yum安装
[root@localhost system]# yum install strace -y
三,查看strace的版本和帮助
1. 查看版本
[root@localhost system]# strace -V strace -- version 4.24 Copyright (c) 1991-2018 The strace developers <https://strace.io>. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Optional features enabled: stack-trace=libdw stack-demangle m32-mpers mx32-mpers
2. 查看帮助
[root@localhost system]# strace -h usage: strace [-CdffhiqrtttTvVwxxy] [-I n] [-e expr]... [-a column] [-o file] [-s strsize] [-P path]... -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS] or: strace -c[dfw] [-I n] [-e expr]... [-O overhead] [-S sortby] -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS] ...
四、strace常用参数
# -f表示跟踪由fork调用所产生的子进程和子线程
# -T 显示每一次调用所耗的时间长
# -t 在输出中的每一行前加上时间信息.
# -tt表示显示跟踪时间, 微秒级别的时间戳
# -e 展示特定的系统调用(例如,open,write等等)
# -o 把strace命令的输出结果保存到指定的文件中
# -r 系统调用之间的相对时间戳
# -c 统计每一系统调用的所执行的时间,次数和出错的次数等
五、strace的应用
1. 追踪指定pid的进程
# -p : 指定进程的pid
[root@localhost system]# strace -p 1042 strace: Process 1042 attached epoll_wait(3, [], 10128, 57) = 0 open("/proc/1042/stat", O_RDONLY) = 6 read(6, "1042 (redis-server) R 1 1042 104"..., 4096) = 368 close(6) = 0 ...
2. 追踪一个进程时加上线程
# -f表示跟踪子进程和子线程
# -T表示显示系统调用的时长
# -tt表示显示跟踪时间
[root@localhost system]# strace -f -T -tt -p 1045 strace: Process 1045 attached 11:07:56.246417 select(7, [3 4], NULL, NULL, NULL
说明:调用的时长:显示为形如:<0.059084>
单位是秒,精确到微秒级别
3. 只追踪指定的操作
# -f表示跟踪子进程和子线程
# -T表示显示系统调用的时长,
# -tt表示显示跟踪时间
# -e 指定特定的系统调用
[root@localhost system]# strace -f -p 1045 -T -tt -e fdatasync strace: Process 1045 attached
4. 追踪一个指定命令的执行
[root@localhost ~]# strace ls execve("/usr/bin/ls", ["ls"], 0x7ffefe415080 /* 30 vars */) = 0 brk(NULL) = 0x1534000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efc35666000 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (没有那个文件或目录) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=44906, ...}) = 0 mmap(NULL, 44906, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efc3565b000 close(3) = 0 open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220j\0\0\0\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=155744, ...}) = 0 mmap(NULL, 2255216, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7efc3521f000 mprotect(0x7efc35243000, 2093056, PROT_NONE) = 0 mmap(0x7efc35442000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x23000) = 0x7efc35442000 mmap(0x7efc35444000, 6512, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7efc35444000 close(3) = 0 ...
5,把跟踪结果保存到指定的文件中
# -o 指定输出文件的路径
[root@localhost ~]# strace -p 1045-o /data/logs/stra_ls.txt
6. 输出系统调用的统计结果,即每个命令的占比
[root@localhost ~]# strace -p 8240 -c strace: Process 8240 attached strace: Process 8240 detached % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 30.22 0.000679 4 143 72 read 26.57 0.000597 8 71 openat 24.25 0.000545 7 71 epoll_wait 10.81 0.000243 3 71 close 8.14 0.000183 2 71 getpid ------ ----------- ----------- --------- --------- ---------------- 100.00 0.002247 427 72 total
六、-e参数trace的常用例子
-e trace=ipc 进程见同学相关,比如shmget等
-e trace=set 只跟踪指定的系统 调用.例如:-e trace=open.
-e trace=desc 和文件描述符相关,比如write/read/select/epoll等
-e trace=file 只跟踪有关文件操作的系统调用.
-e trace=process 只跟踪有关进程控制的系统调用.
-e trace=network 跟踪与网络有关的所有系统调用.
-e trace=signal 跟踪所有与系统信号有关的 系统调用
-e trace=ipc 跟踪所有与进程通讯有关的系统调用
例:跟踪与网络有关的系统调用
[root@blog ~]# strace -Te trace=network curl
七、strace结果中的常见分析
1. 如果应用打开分区时使用O_DIRECT,O_DIRECT 表示以直接读取的方式打开,这会绕过系统的缓存。
直接从磁盘读写的速度,自然远慢于对缓存的读写。会导致速度变慢
2. write(3, "2018-12-05 15:23:01,709 - __main"..., 314572844 ) = 314572844
表示进程向文件描述符编号为 3 的文件中,写入了 300MB 的数据
3. write 或者 fdatasync都属于对磁盘的写操作
八、查看centos的版本
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 8.0.1905 (Core)