Linux系统性能分析利器strace
strace
可以跟踪一个进程的系统调用和信号,不仅可以帮助开发人员和管理员更好的理解应用程序的行为,还可以帮助开发开发人员调试问题,分析性能。
我们知道,应用程序是不可以直接操作硬件和底层资源。如果要操作底层硬件的话,就需要执行内核提供的系统调用函数,通过 strace
命令可以跟踪程序所有的系统调用,相当于给用户提供一种观测底层资源操作的能力。
安装strace
对于大多数操作系统,都可以通过软件包管理器来进行安装
1. ubuntu
1 | apt-get install strace -y |
2. centos
1 | yum install strace -y |
基本用法
1. 基本用法
strace
用法非常简单,我们在要跟踪的程序前面加上 strace
即可
1 | $ strace ls |
可以看到与 ls
命令相关的系统调用都被打印了出来。=
左侧是系统调用函数名称与参数,右侧是函数调用后的返回值
2. 重定向输出
默认情况下,strace
会把所有的系统调用信息打印到屏幕上,如果信息过多不便于观察分析,可以将信息重定向到文件中
1 | strace -o output.txt ls |
3. 跟踪正在运行的进程
strace
除了可以跟踪一个新启动的程序外,还可以跟踪正在运行的程序。我们需要先获取要跟踪程序的进程 PID
1 | strace -p 533880 |
通过 -p
选项,指定需要跟踪的程序
4. 显示时间
通过 -t
选项,可以在每个系统调用信息前边显示时间戳
1 | strace -t ls |
-t
:在输出中的每一行前加上时间信息-tt
:在输出中的每一行前加上时间信息,微秒级-ttt
:微秒级,以时间戳格式输出
过滤输出
从上边我们知道,strace
会把捕捉到的所有系统调用都打印出来了。而在程序调试分析时,我们往往并不希望看到所有的系统调用,而是指定具体的系统调用。
1. 跟踪指定的系统调用
1 | strace -e trace=open,read,close ls |
上边的命令只跟踪 open
、read
、close
相关的系统调用。除了具体的系统调用外,还支持指定如下的方式
-e trace=file
:只跟踪有关文件操作的系统调用-e trace=process
:只跟踪有关进程控制的系统调用-e trace=network
:跟踪与网络有关的所有系统调用-e trace=signal
:跟踪所有与系统信号有关的系统调用-e trace=ipc
:跟踪所有与进程通讯有关的系统调用
2. 只跟踪指定的信号
通过 -e signal
指定要跟踪的信号
1 | strace -e signal=SIGIO ls |
3. 只跟踪从指定的文件来读数据
1 | strace -e read=3,5 myapp |
4. 只跟踪从指定的文件来写数据
1 | strace -e write=4,6 myapp |
统计功能
strace
除了可以提供具体的系统调用信息外,还能提供信息统计功能。它可以统计在一段时间内,每个系统调用的次数、时间消耗、时间占比、错误次数等信息。
这些信息对排查程序问题非常有帮助,它可以告诉你哪个系统调用消耗时间最长,哪个系统调用错误较高,哪个系统调用次数最多,在问题排查时非常有用。
strace
通过 -c
选项就可以这些信息的统计
1 | $ strace -c ls |
在程序执行完毕后,就会输出相应的统计信息。如果你使用 -p
选项,正在跟踪一个正在运行的程序时,统计信息会在你执行 Ctrl + C
之后才会显示出来。
如果想统计每个系统调用的消耗时间,可以通过 -T
选项来实现
1 | $ strace -T -e trace=read ls |
可以看到,系统调用信息后边增加了耗时的统计
常用选项
下边总结一下 strace
的常见选项
-c
:统计每一系统调用的所执行的时间,次数和出错的次数等-d
:输出strace关于标准错误的调试信息-f
:跟踪由fork调用所产生的子进程-F
:尝试跟踪vfork调用-h
:输出简要的帮助信息-i
:输出系统调用的入口指针-q
:禁止输出关于脱离的消息-r
:打印出相对时间-t
:在输出中的每一行前加上时间信息-tt
:显示微秒级时间-ttt
:微秒级输出(以秒显示)-T
:显示每一调用所耗的时间-v
:输出所有的系统调用-V
:输出strace的版本信息-x
:以十六进制形式输出非标准字符串-xx
:所有字符串以十六进制形式输出-a column
:设置返回值的输出位置-e expr
:指定一个表达式,用来控制如何跟踪-e trace=set
:只跟踪指定的系统调用-e trace=file
:只跟踪有关文件操作的系统调用-e trace=process
:只跟踪有关进程控制的系统调用-e trace=network
:跟踪与网络有关的所有系统调用-e strace=signal
:跟踪所有与系统信号有关的 系统调用-e trace=ipc
:跟踪所有与进程通讯有关的系统调用-e abbrev=set
:设定strace输出的系统调用的结果集-e raw=set
:将指定的系统调用的参数以十六进制显示-e signal=set
:指定跟踪的系统信号-e read=set
:输出从指定文件中读出的数据-e write=set
:输出写入到指定文件中的数据-o filename
:将strace的输出写入文件filename-p pid
:跟踪指定的进程pid-s strsize
:指定输出的字符串的最大长度-u username
:以username的UID和GID执行被跟踪的命令