返回
Featured image of post Linux 命令 —— strace

Linux 命令 —— strace

strace

strace - 跟踪系统调用和信号。

在最简单的情况下,strace 运行指定的命令直到它退出。 它拦截并记录由进程调用的系统调用和进程接收的信号。 每个系统调用的名称,其参数和返回值都打印在标准错误或使用-o选项指定的文件上。 strace 是一种有用的诊断,指导和调试工具。 跟踪中的每一行都包含系统调用名称,后跟括号中的参数及其返回值。如:

open("/dev/null", O_RDONLY) = 3

系统调用错误,如:(返回 -1,并打印出错原因)

open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

信号,如:

sigsuspend([] <unfinished ...>
--- SIGINT (Interrupt) ---
+++ killed by SIGINT +++

正在执行系统调用的同时,另一个线程/进程调用另一个系统调用,则 strace 将尝试保留这些事件的顺序并将正在进行的调用标记为未完成。 当调用返回时,它将被标记为已恢复:

[pid 28772] select(4, [3], NULL, NULL, NULL <unfinished ...>
[pid 28779] clock_gettime(CLOCK_REALTIME, {1130322148, 939977000}) = 0
[pid 28772] <... select resumed> )      = 1 (in [3])

系统调用被中断后重启,如:

read(0, 0x7ffff72cf5cf, 1)              = ? ERESTARTSYS (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
rt_sigreturn(0xe)                       = 0
read(0, ""..., 1)                       = 0

解引用结构指针,并根据需要显示成员。在所有情况下,参数都以尽可能类似 C 的方式格式化。例如“ls -l /dev/null”:

lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0

解引用字符指针:

read(3, "root::0:0:System Administrator:/"..., 1024) = 422

用法

strace  [-CdffhiqrtttTvVxxy]  [-In]  [-bexecve]  [-eexpr]...   [-acolumn] [-ofile] [-sstrsize] [-Ppath]... -ppid... / [-D]
[-Evar[=val]]... [-uusername] command [args]

strace -c[df] [-In] [-bexecve] [-eexpr]...  [-Ooverhead] [-Ssortby] -ppid... / [-D] [-Evar[=val]]... [-uusername]  command
[args]

选项

-c          统计系统调用的次数、出错次数。在Linux上,这会尝试显示系统时间(在内核中运行的CPU时间),与墙上时间无关。
            如果 -c 和 -f 或 -F 一起使用,仅保留所有跟踪进程的聚合总计。

-C          与-c类似,但在进程运行时也会打印常规输出。

-D          将跟踪器进程作为分离的孙子(detached grandchild)进程运行,而不是作为tracee的父进程。 
            这通过将tracee保持为调用进程的直接子进程来减少strace的可见效果

-d          在标准错误上输出strace的debug信息。

-f          跟踪由fork/vfork/clone调用所产生的子进程。
            注意,如果是多线程,则"-p PID -f"将附加到PID进程的所有线程,而不仅是附加到带有 "thread_id = PID" 的线程。


-ff         如果"-o filename"选项生效,则每个进程的跟踪信息都将写入filename.pid中,其中pid是每个进程的进程ID。 
            这与-c不兼容,因为不保留每进程计数。

-F          此选项现已过时,它具有与-f相同的功能。

-h          打印帮助。

-i          在系统调用时打印指令指针。

-q          不显示有关附加/分离(attaching/detaching)的消息。
            当输出重定向到文件并且命令是直接运行的(而不是附加(attaching))的,会自动发生这种情况。

-qq         不显示有关进程退出状态的消息。

-r          在进入每个系统调用时打印相对时间戳。 这记录了连续系统调用开始之间的时间差。

-t          在每一行跟踪信息前面添加时间(一天中的时间),最小单位是秒。

-tt         在每一行跟踪信息前面添加时间(一天中的时间),最小单位是毫秒。

-ttt        打印的时间将包括微秒,并且前导部分将被打印为自纪元以来的秒数。

-T          显示系统调用花费的时间。 这记录了每个系统调用的开始和结束之间的时间差。

-v          打印environment、stat、termios等调用的未缩写版本。 这些结构在调用中非常常见,因此默认行为显示结构成员的合理子集。 使用此选项可获得所有细节。

-V          打印strace的版本.

-x          以十六进制字符串格式打印所有非ASCII字符串。

-xx         以十六进制字符串格式打印所有字符串。

-y          打印与文件描述符参数关联的路径。

-a column   对齐特定列中的返回值(默认列40)。

-b syscall  如果到达指定的系统调用,则从跟踪的进程中分离。 目前,仅支持execve系统调用。
            这个选项很有用,如果你想要跟踪多线程的进程(需要-f),但不想跟踪其(可能非常复杂的)孩子。

-e expr     用于修改要跟踪的事件或如何跟踪它们的一个限定表达式。 表达式的格式是:
                     [qualifier=][!]value1[,value2]...
              
            qualifier是trace,abbrev,verbose,raw,signal,read,write之一,value是依赖于限定符的符号或数字。 
            默认限定符是trace。使用感叹号会取消该组值。 例如,"-e open"表示字面意思"-e trace=open",这意味着仅跟踪“open”的系统调用。 
            相比之下,“-e trace=open”表示跟踪除open之外的每个系统调用。 
            此外,特殊值all和none都有明显的含义。

            请注意,即使在引用的参数中,某些shell也会使用感叹号进行历史记录扩展。 
            注意,有些shell使用"!"来执行历史记录里的命令,如果是这样,您必须使用反斜杠转义感叹号。

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

-e trace=file
            只跟踪有关文件操作的系统调用。(跟踪所有以一个文件名作为参数的系统调用)
            你可以看做是:-e trace=open,stat,chmod,unlink,...
            这对于查看进程引用的文件很有用。
            此外,使用缩写将确保您不会意外忘记在列表中包含类似lstat的调用。 

-e trace=process
            只跟踪有关进程控制的系统调用。 这对于查看进程的fork,wait和exec步骤非常有用。

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

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

-e trace=ipc
            跟踪所有与IPC相关的系统调用.

-e trace=desc
            跟踪所有与文件描述符相关的系统调用.

-e trace=memory
            跟踪与内存映射相关的所有系统调用.

-e abbrev=set
            设定strace输出的系统调用的结果集。"-v"选项等于“abbrev=none”,默认为“abbrev=all”.

-e verbose=set
            对指定系统调用集的结构进行解引用。 默认值为 "verbose=all"。

-e raw=set
            将指定的系统调用的参数以十六进制显示。(为指定的系统调用集打印原始的,未解码的参数。)
            如果您不信任解码或者您需要知道参数的实际数值,这将非常有用。

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

-e read=set 以完整的16进制或ASCII形式,输出所有从指定文件描述符集中读取的数据。例如: "-e read=3,5",读文件描述符3和5上的所有输入活动。
            请注意请注意,这与read(2)系统调用的正常跟踪无关,该调用由选项"-e trace=read"控制。

-e write=set
            以完整的16进制或ASCII形式,输出所有写到指定文件描述符集的数据。

-I interruptible
            当strace可以被信号中断(例如按^C)
            1:没有信号被阻挡; 
            2:解码系统调用时阻塞致命信号(默认); 
            3:致命信号总是被阻止(默认为'-o FILE PROG';
            4:致命信号和SIGTSTP(^Z)始终被阻止(有助于使strace -o FILE PROG不在^Z上停止)。
-o filename
            把跟踪信息输出到filename指定的文件而不是输出到stderr。
            如果指定"-ff"则会使用filename.pid。
            如果参数以"|""!"开始,则参数的其余部分会被视作一个命令,并且所有输出都会通过管道给它(此命令)。【???】
            这样可以方便地将调试输出传递给程序,而不会影响已执行程序的重定向。【???】
            [If the argument begins with `|' or with `!' then the rest of the argument is treated as a command and all output is piped to it.  
            This is convenient for piping the debugging output to a program without affecting the redirections of executed programs.]

-O overhead
            将跟踪系统调用的overhead(开销)设置为overhead微秒。
            这对于覆盖默认启发式方法非常有用,可以猜测在使用-c选项进行计时系统调用时仅花费多少时间。
            可以通过在没有跟踪的情况下对给定程序运行进行计时(使用time(1))并将累积的系统调用时间与使用-c产生的总数进行比较来测量启发式的准确性。

-p pid
            使用进程ID pid附加到进程并开始跟踪。
            可以通过键盘中断信号(CTRL-C)随时终止跟踪。 
            strace会通过将自己从跟踪过程中分离出来而让它(它们)继续运行。
            多个-p选项可用于附加到许多进程。 支持-p"`pidof PROG`"语法。

-P path     仅跟踪系统调用访问的路径。 多个-P选项可用于指定多个路径。

-s strsize  指定要打印的最大字符串大小(默认值为32)。 请注意,文件名不被视为字符串,并且始终完整打印。

-S sortby   按指定条件对-c选项打印的直方图的输出进行排序。 
            合法值是时间(time),系统调用(call),名称(name),默认为时间。(根据什么来排序的意思)

-u username 使用用户名所在的"用户ID",“组ID“和”补充组“来运行命令。
            此选项仅在以root身份运行,并且能够正确执行setuid(和/或)setgid二进制文件时有用。 
            除非使用此选项,否则setuid和setgid程序在没有有效权限的情况下执行。

-E var=val  在其环境变量列表中运行带有var=val的命令。

-E var      在将var传递给命令前,从继承的环境变量列表中将var删除。

示例

显示每个系统调用的相对时间

strace -r ls ls 表示 ls 命令

显示系统调用时间(一天当中的时间/纪元时间)

strace -t ls strace -tt ls strace -ttt ls

打印与文件描述符相关联的路径

strace -y ls

跟踪指定进程

strace -p 123

把输出存在文件中

strace -o ls.log ls

相关

  • ltrace(1)
  • time(1)
  • ptrace(2)
  • proc(5)

参考

相信美好的事情即将发生。
Built with Hugo
Theme Stack designed by Jimmy