一、strace

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

    当然strace与专业的调试工具比如说gdb之类的是没法相比的,因为它不是一个专业的调试器。

     strace的最简单的用法就是执行一个指定的命令,在指定的命令结束之后它也就退出了。在命令执行的过程中,strace会记录和解析命令进程的所有系统调用以及这个进程所接收到的所有的信号值。

二、strace 命令 的使用

 1、语法 :

#  strace [ -dffhiqrtttTvxx ] [ -a column ] [ -e expr ] ... [ -o file ] [-p pid ] ... 

         [ -s strsize ] [ -u username ] [ -E var=val ] ... [ -E var ]... [ command [ arg ... ] ] strace -c [ -e expr ] ... 

         [ -O overhead ] [ -S sortby ] [ command [ arg... ] ] 

2、选项: 

  • -c      统计每一系统调用的所执行的时间,次数和出错的次数等.

  • -d     输出strace关于标准错误的调试信息.

  • -f      跟踪由fork调用所产生的子进程. 

  • -ff     如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.

  • -F     尝试跟踪vfork调用.在-f时,vfork不被跟踪. 

  • -h     输出简要的帮助信息. 

  • -i      输出系统调用的入口指针.

  • -q     禁止输出关于脱离的消息. 

  • -r      打印出相对时间关于,,每一个系统调用.

  • -t      在输出中的每一行前加上时间信息.

  • -tt     在输出中的每一行前加上时间信息,微秒级.

  • -ttt    微秒级输出,以秒了表示时间.

  • -T      显示每一调用所耗的时间.

  • -v      输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.

  • -V      输出strace的版本信息.

  • -x      以十六进制形式输出非标准字符串.

  • -xx     所有字符串以十六进制形式输出.

  • -a column    设置返回值的输出位置.默认 为40.

  • -e expr        指定一个表达式,用来控制如何跟踪.

    格式:[qualifier=][!]value1[,value2]... qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.

    value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.

    例如:

          -eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open 表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none. 注意有些shell使用!来执行历史记录里的命令,所以要使用\\. 

  • -e trace=set     只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.

  • -e trace=file      只跟踪有关文件操作的系统调用. 

  • -e trace=process   只跟踪有关进程控制的系统调用. 

  • -e trace=network  跟踪与网络有关的所有系统调用.

  • -e strace=signal    跟踪所有与系统信号有关的 系统调用.

  • -e trace=ipc           跟踪所有与进程通讯有关的系统调用.

  • -e abbrev=set       设定strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all. 

  • -e raw=set            将指定的系统调用的参数以十六进制显示. 

  • -e signal=set         指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号. 

  • -e read=set           输出从指定文件中读出 的数据.例如: -e read=3,5

  • -e write=set          输出写入到指定文件中的数据.

  • -o filename            将strace的输出写入文件filename 

  • -p pid                     跟踪指定的进程pid. 

  • -s strsize               指定输出的字符串的最大长度.默认为32.文件名一直全部输出.

  • -u username          以username的UID和GID执行被跟踪的命令.


三、strace 示例

1、追踪系统调用

    $./test           //直接执行
    $strace ./test    //通过strace 执行

2、跟踪信号传递 

    先 $strace ./test,等到等待输入的画面的时候不要输入任何东西,然后打开另外一个窗口,输入如下的命令$ killall test   ,即可观察进程接收信号的情况。
3、系统调用统计

     strace不光能追踪系统调用,通过使用参数-c,它还能将进程所有的系统调用做一个统计分析显示出来。

    strace的统计,执行带-c参数的strace: $ strace -c ./test

    其结果显示:调用了那些系统函数,调用次数多少,消耗了多少时间等等这些信息,对我们分析一个程序来说是非常有用的。

4、其他参数

(1)参数  -o  用在将strace的结果输出到文件中

    如果不指定-o参数的话,默认的输出设备是STDERR,也就是说使用”-o filename”和” 2>filename”的结果是一样的。 

# 这两个命令都是将strace结果输出到文件test.txt中 
strace -c -o test.txt ./test 
strace -c ./test 2 > test.txt

(2)对系统调用进行计时

 strace可以使用参数  -T 将每个系统调用所花费的时间打印出来,每个调用的时间花销现在在调用行最右边的尖括号里面。 

 $strace -T ./test

(3) 系统调用的时间

 这是一个很有用的功能,strace会将每次系统调用的发生时间记录下来,只要使用  -t/tt/ttt  三个参数就可以看到效果了。

参数名         输出样式        说明
-t 10:33:04 exit_group(0)  输出结果精确到秒
-tt 10:33:48.159682 exit_group(0) 输出结果精确到微秒
-ttt 1262169244.788478 exit_group(0) 精确到微妙 ,而且时间表示为unix时间戳

(4)  截断输出
 -s参数用于指定trace结果的每一行输出的字符串的长度。

test程序中 -s 参数对结果有什么影响,现指定-s为20,然后在read的是是很我们输入一个超过20个字符的数字串 

$ strace -s 20 ./test

read(0, 2222222222222222222222222 // 我们输入的2一共有25个 

"22222222222222222222"..., 1024) = 26 // 而我们看到的结果中2只有20个

(5) trace一个现有的进程

 strace不光能自己初始化一个进程进行trace,还能追踪现有的进程,参数-p就是取这个作用的。

$  strace -p pid