Linux 中的 strace 是一个可用于诊断、调试和教学的 Linux 用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。
strace 底层使用内核的 ptrace 特性来实现其功能。 strace 命令是一个集诊断、调试、统计与一体的工具,我们可以使用 strace 对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。
当然 strace 与专业的调试工具比如说 gdb 之类的是没法相比的,因为它不是一个专业的调试器。 strace 的最简单的用法就是执行一个指定的命令,在指定的命令结束之后它也就退出了。在命令执行的过程中,strace 会记录和解析命令进程的所有系统调用以及这个进程所接收到的所有的信号值。
strace 是一个非常简单的工具,它可以跟踪系统调用的执行。最简单的方式,它可以从头到尾跟踪 binary 的执行,然后以一行文本输出系统调用的名字,参数和返回值。
其实它可以做的更多:
strace cmd [option]
参数 | 描述 |
---|---|
cmd | 命令。 |
选项 | 描述 |
---|---|
-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 | 指定一个表达式,用来控制如何跟踪。 |
-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 write=set | 输出写入到指定文件中的数据。 |
-o filename | 将 strace 的输出写入文件 filename。 |
-p pid | 跟踪指定的进程 pid。 |
-s strsize | 指定输出的字符串的最大长度,默认为 32,文件名一直全部输出。 |
-u username | 以 username 的 UID 和 GID 执行被跟踪的命令。 |
实例 | 描述 |
---|---|
strace process | 查看进程系统调用。 |
strace -p pid | 查看进程系统调用。 |
strace -c process | 查看系统调用的概要,执行时间,错误等等。 |
strace -p 12323 -w=write,read | 只查看 write 和 read 的系统调用。 |
strace -o file.log -p pid | 将结果保存到文件中。 |
strace -o output.txt -T -tt -e trace=all -p pid | 跟踪 pid 进程的所有系统调用(-e trace=all),并统计系统调用的花费时间,以及开始时间(并以可视化的时分秒格式显示),最后将记录结果存在 output.txt 文件里面。 |
strace 命令有两种运行模式:一种是通过它启动要跟踪的进程。用法很简单,在原本的命令前加上 strace 即可。比如我们要跟踪 “ls -lh /var/log/messages” 这个命令的执行,可以这样:
strace ls -lh /var/log/messages
另外一种运行模式,是跟踪已经在运行的进程,在不中断进程执行的情况下,理解它在干嘛。 这种情况,给strace 传递个 -p pid 选项即可。
比如,有个在运行的 some_server 服务,第一步,查看 pid:
pidof some_server 17553
得到其 pid 17553 然后就可以用 strace 跟踪其执行:
strace -p 17553
完成跟踪时,按 ctrl + C 结束 strace 即可。
strace process
我们使用 strace 查看 ls 命令的系统调用,具体命令如下:
strace ls
运行后,终端输出如下:
我们看到,此时输出了 ls 命令的系统调用。
strace -p pid
我们使用 strace 查看正在运行的进程的系统调用,具体命令如下:
strace -p 20718
运行后,终端输出如下:
我们看到,此时输出了进程 id 为 20718 的系统调用。
Linux 中的 strace 是一个可用于诊断、调试和教学的 Linux 用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等。
strace 底层使用内核的 ptrace 特性来实现其功能。 strace 命令是一个集诊断、调试、统计与一体的工具,我们可以使用 strace 对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。