strace是一个非常简单的工具,它可以跟踪系统调用的执行。它常用来跟踪进程执行时的系统调用和所接受的信号。在调试的时候,strace能帮助我们追踪到一个程序所执行的而系统调用。当我们想知道程序和操作系统如何交互的时候,这时极其方便的,比如我们想知道执行了哪些系统调用,并且以何种顺序执行。我们知道,在linux中,进程不能直接访问硬件设备,当进程需要直接访问硬件设备(比如读取磁盘文件,接受网络数据时),必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strance可以追踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间等等。

       同时,strance是一个集诊断,调试,统计于一体的工具。我们可以使用strance对应用的的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。


我们先来看看strace的命令都有哪些:

                                    strace常用命令学习_常用

接下来我们通过一个打印“hello world”小程序来练习上面一些常用的选项:

       strace常用命令学习_常用_02

       从上面我们可以看到,当我们用strace执行test时,系统首先调用execv函数开始一个新的进程,接着进行一些环境初始化的一些操作,然后再调用write函数将“hello world”输出到屏幕上,最后调用exit_group退出,就这样完成整个程序的执行过程。


用-s参数实现截断输出:

     -s参数用来指定trace的结果的每一行的输出长度,同样还是上面的程序,我们看看加了-s参数后的变化:

       strace常用命令学习_常用_03   

       从上面的结果我们可以看到,本来我们是要输出“hello world”的,当我们加上-s 选项之后,输出了“hell”,实现了截断。


我们再来看看strace的跟踪信号传递功能:

      我们这里还用上面的test程序,来观察进程接受信号的情况。我们先strace ./test,然后打开另外一个窗口,输入如下的命令 killall test,这时我们会看到程序退出了,结果如下:

      strace常用命令学习_strace_04

     上面的现象可以体现出来用strace可以跟踪进程执行时所接受的信号。


用-c参数还能将进程所有的系统调用做一个统计分析,如下的现象:

      strace常用命令学习_常用_05

     从上图我们可以很清楚的知道我们执行一个进程时,调用了哪些系统函数,调用的次数,消耗的时间等信息,这对我们分析一个程序来说是非常有用的。


用-o选项实现重定向输出:参数-o用于将strace的输出重定向到文件中,如果不指定-o的话,默认的输出是stderr,格式是 -o filename,和使用2 > filename是一样的。我们来看看:

    strace常用命令学习_命令_06


       用-T选项可以打印出每个系统调用所花费的时间,也就是每行最右边的尖括号里面(我在图中用红颜色的框画出来的)。这是一个很有用的功能,strace会将系统调用每次的时间记录下来,我们可以使用-t/tt/ttt看到,比如下面:

      strace常用命令学习_命令_07

      我们来说一下这三个参数的区别:-t 输出结果精确到秒,-tt输出结果精确到微秒,-ttt精确到微秒,而且时间表示为unix时间戳。


用-p追踪一个现有的进程,用法是 strace -p pid,我们看如下例子:

     strace常用命令学习_strace_08

      我们的程度是先获得进程的id,并输出“hello world”,然后sleep 30秒,在这期间,我们用strace追踪该进程,输出上图的信息,30秒后,进程结束,死奥用seit_group函数。


用-e选项来进行特定的系统调用(例如open,write)等:

        strace常用命令学习_strace_09

      如上,我们我规定查看open的系统调用,并输出了相应的信息。


用-r参数展示系统调用之间的相对时间戳:

      strace常用命令学习_命令_10

 

    其他选项的例子就不一一例举了,以上几个选项时比较常用的。