strace是一个非常简单的工具,它可以跟踪系统调用的执行。它常用来跟踪进程执行时的系统调用和所接受的信号。在调试的时候,strace能帮助我们追踪到一个程序所执行的而系统调用。当我们想知道程序和操作系统如何交互的时候,这时极其方便的,比如我们想知道执行了哪些系统调用,并且以何种顺序执行。我们知道,在linux中,进程不能直接访问硬件设备,当进程需要直接访问硬件设备(比如读取磁盘文件,接受网络数据时),必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strance可以追踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间等等。
同时,strance是一个集诊断,调试,统计于一体的工具。我们可以使用strance对应用的的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。
我们先来看看strace的命令都有哪些:
接下来我们通过一个打印“hello world”小程序来练习上面一些常用的选项:
从上面我们可以看到,当我们用strace执行test时,系统首先调用execv函数开始一个新的进程,接着进行一些环境初始化的一些操作,然后再调用write函数将“hello world”输出到屏幕上,最后调用exit_group退出,就这样完成整个程序的执行过程。
用-s参数实现截断输出:
-s参数用来指定trace的结果的每一行的输出长度,同样还是上面的程序,我们看看加了-s参数后的变化:
从上面的结果我们可以看到,本来我们是要输出“hello world”的,当我们加上-s 选项之后,输出了“hell”,实现了截断。
我们再来看看strace的跟踪信号传递功能:
我们这里还用上面的test程序,来观察进程接受信号的情况。我们先strace ./test,然后打开另外一个窗口,输入如下的命令 killall test,这时我们会看到程序退出了,结果如下:
上面的现象可以体现出来用strace可以跟踪进程执行时所接受的信号。
用-c参数还能将进程所有的系统调用做一个统计分析,如下的现象:
从上图我们可以很清楚的知道我们执行一个进程时,调用了哪些系统函数,调用的次数,消耗的时间等信息,这对我们分析一个程序来说是非常有用的。
用-o选项实现重定向输出:参数-o用于将strace的输出重定向到文件中,如果不指定-o的话,默认的输出是stderr,格式是 -o filename,和使用2 > filename是一样的。我们来看看:
用-T选项可以打印出每个系统调用所花费的时间,也就是每行最右边的尖括号里面(我在图中用红颜色的框画出来的)。这是一个很有用的功能,strace会将系统调用每次的时间记录下来,我们可以使用-t/tt/ttt看到,比如下面:
我们来说一下这三个参数的区别:-t 输出结果精确到秒,-tt输出结果精确到微秒,-ttt精确到微秒,而且时间表示为unix时间戳。
用-p追踪一个现有的进程,用法是 strace -p pid,我们看如下例子:
我们的程度是先获得进程的id,并输出“hello world”,然后sleep 30秒,在这期间,我们用strace追踪该进程,输出上图的信息,30秒后,进程结束,死奥用seit_group函数。
用-e选项来进行特定的系统调用(例如open,write)等:
如上,我们我规定查看open的系统调用,并输出了相应的信息。
用-r参数展示系统调用之间的相对时间戳:
其他选项的例子就不一一例举了,以上几个选项时比较常用的。