您的位置:首页 > 运维架构 > Linux

strace linux 下程序的系统调用和信号调用跟踪工具

2012-01-10 10:01 375 查看
 

strace 简介

strace 命令是一种强大的工具, 能够显示任何由用户空间程式发出的系统调用. strace 显示这些调用的参数并返回符号形式的值. strace 从内核接收信息, 而且无需以任何特别的方式来构建内核. strace 的每一行输出包括系统调用名称, 然后是参数和返回值.

调用方法为:

调用:

strace [ -dffhiqrtttTvxx ] [ -acolumn ] [ -eexpr ] ...

[ -ofile ] [ -ppid ] ... [ -sstrsize ] [ -uusername ] [ command [ arg ... ] ]

strace -c [ -eexpr ] ... [ -Ooverhead ] [ -Ssortby ] [ command [ arg ... ] ]

参数:

-c -- count time, calls, and errors for each syscall and report summary

-f -- follow forks, -ff -- with output into separate files

-F -- attempt to follow vforks, -h -- print help message

-i -- print instruction pointer at time of syscall

-q -- suppress messages about attaching, detaching, etc.

-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs

-T -- print time spent in each syscall, -V -- print version

-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args

-x -- print non-ascii strings in hex, -xx -- print all strings in hex

-a column -- alignment COLUMN for printing syscall results (default 40)

-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...

   options: trace, abbrev, verbose, raw, signal, read, or write

-o file -- send trace output to FILE instead of stderr

-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs

-p pid -- trace process with process id PID, may be repeated

-s strsize -- limit length of print strings to STRSIZE chars (default 32)

-S sortby -- sort syscall counts by: time, calls, name, nothing (default time)

-u username -- run command as username handling setuid and/or setgid

-E var=val -- put var=val in the environment for command

-E var -- remove var from the environment for command

例子:

例子1:
执行如下命令:

strace –o s_ff ./ffmpeg

则会将strace的运行结果输出到s_ff文件中:

execve("/usr/local/bin/ffmpeg", ["ffmpeg"], [/* 46 vars */]) = 0

brk(0)                                  = 0x922e000

access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)

mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7808000

access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)

open("/etc/ld.so.cache", O_RDONLY)      = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=53383, ...}) = 0
open("/usr/lib/i486-linux-gnu/i686/cmov/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/lib/i486-linux-gnu/i686/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/lib/i486-linux-gnu/sse2/cmov/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/lib/i486-linux-gnu/sse2/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/lib/i486-linux-gnu/cmov/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/lib/i486-linux-gnu/libavdevice.so.52", O_RDONLY) = -1 ENOENT (No such file or directory)

可以看到只有open的函数调用

这些功能都是通过-e来实现的

-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执行被跟踪的命令.

例子3:

strace还可以通过进程ID来进行对进程的绑定。这样在调试网络程序或者其它僵死程序是特别有用。以下是我绑定在我ubuntu上的apt程序进输出的结果:

Process 9012 attached - interrupt to quit

select(4, NULL, [3], NULL, {101, 527785}) = 1 (out [3], left {98, 971795})

getsockopt(3, SOL_SOCKET, SO_ERROR, [110], [4]) = 0

open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)

当然strace可以也可用来统计系统调用的次数和时间这样可以帮助你分析程序的瓶颈。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息