strace是一个有用的诊断、指导和调试工具。系统管理员、诊断专家和故障解决人员将发现,对于解决源代码不易获得的程序的问题,这是非常宝贵的,因为它们不需要重新编译以跟踪它们。学生、黑客和过分好奇的人会发现,通过跟踪甚至是普通程序,可以了解到大量关于系统及其系统调用的信息。程序员会发现,由于系统调用和信号是发生在用户/内核界面上的事件,因此仔细检查该边界对于错误隔离、健全性检查和尝试捕获竞争条件非常有用。strace运行时它拦截并记录进程调用的系统调用和进程接收的信号。每个系统调用的名称、参数及其返回值都打印在标准错误上或打印到使用-o选项指定的文件中。
[root@s142 ~]# yum install -y strace
[root@s142 ~]# strace -V
strace – version 4.24
…
[root@s142 ~]# strace -h
usage: strace [-CdffhiqrtttTvVwxxy] [-I n] [-e expr]…
…
直接在命令前面加上strace命令就可以跟踪命令的执行过程了,会详细的显示命令过程中执行的命令、系统调用、进程接收的信号等。
[root@s142 ~]# strace ls -h
execve(“/usr/bin/ls”, [“ls”, “-h”], 0x7ffcb2bef228 /* 25 vars */) = 0
brk(NULL)
使用-c参数可以显示strace命令的统计结果,显示命令执行了哪些系统调用信号、耗时、各系统调用次数等。
[root@s142 ~]# strace -c ls -h
anaconda-ks.cfg
% time seconds usecs/call calls errors syscall
strace默认查看所有调用信号,使用-e参数可以查看指定类型的调用,减少输出信息。支持的信号包括:trace, abbrev, verbose, raw, signal, read, write, fault, inject, kvm等。
[root@s142 ~]# strace -e open ls -h
open(“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libselinux.so.1”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libcap.so.2”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libacl.so.1”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libc.so.6”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libpcre.so.1”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libdl.so.2”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libattr.so.1”, O_RDONLY|O_CLOEXEC) = 3
open(“/lib64/libpthread.so.0”, O_RDONLY|O_CLOEXEC) = 3
open(“/usr/lib/locale/locale-archive”, O_RDONLY|O_CLOEXEC) = 3
anaconda-ks.cfg
+++ exited with 0 +++
strace输出默认是没有时间信息的,使用-t或者-tt参数我们可以打印命令执行的时间,精确到毫秒。
[root@s142 ~]# strace -t -e open ls -h
03:23:18 open(“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) = 3
03:23:18 open(“/lib64/libselinux.so.1”, O_RDONLY|O_CLOEXEC) = 3
如果希望保存strace命令执行的结果,我们可以使用-o参数将内容输出到指定文件。
[root@s142 ~]# strace -t -o /tmp/strace-ls.log ls -h
anaconda-ks.cfg
[root@s142 ~]# cat /tmp/strace-ls.log
03:25:02 execve(“/usr/bin/ls”, [“ls”, “-h”], 0x7fff28de1af0 /* 25 vars */) = 0
如果是排查已经正在运行的进程的问题,我们可以使用-p参数跟踪指定进程的系统信号调用。
[root@s142 ~]# sh test.sh &
[1] 5859
[root@s142 ~]# 开始测试
[root@s142 ~]# strace -t -e trace=process -f -p 5859
strace: Process 5859 attached
03:38:58 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 5860
用法:strace [参数] 命令 [命令参数]
参数 | 参数类型 | 参数说明 |
---|---|---|
-a column | 输出格式参数 | 用于打印系统调用结果的对齐列(默认为40) |
-i | 输出格式参数 | 在系统调用时打印指令指针 |
-k | 输出格式参数 | 获取每个系统调用之间的堆栈跟踪 |
-o file | 输出格式参数 | 将跟踪输出发送到文件而不是stderr |
-q | 输出格式参数 | 抑制有关附加、分离等的消息。 |
-r | 输出格式参数 | 打印相对时间戳 |
-s strsize | 输出格式参数 | 将打印字符串的长度限制为STRSIZE字符(默认为32) |
-t | 输出格式参数 | 打印绝对时间戳 |
-tt | 输出格式参数 | 使用usecs打印绝对时间戳 |
-T | 输出格式参数 | 打印每个系统调用花费的时间 |
-x | 输出格式参数 | 以十六进制打印非ascii字符串 |
-xx | 输出格式参数 | 以十六进制打印所有字符串 |
-X format | 输出格式参数 | 设置打印命名常量和标志的格式 |
-y | 输出格式参数 | 与文件描述符参数关联的打印路径 |
-yy | 输出格式参数 | 打印与套接字文件描述符关联的协议特定信息 |
-c | 统计参数 | 统计每个系统调用的时间、调用和错误,并报告摘要 |
-C | 统计参数 | 像-c一样,也可以打印常规输出 |
-O overhead | 统计参数 | 将跟踪系统调用的开销设置为开销usecs |
-S sortby | 统计参数 | 按以下方式对系统调用计数排序:时间、调用、名称、无(默认时间) |
-w | 统计参数 | 统计系统调用延迟(默认为系统时间) |
-e expr | 过滤参数 | 限定表达式,表达式值可以是trace, abbrev, verbose, raw, signal, read, write, fault, inject, kvm |
-P path | 过滤参数 | 跟踪访问路径 |
-b execve | 跟踪参数 | 执行系统调用时分离 |
-D | 跟踪参数 | 将跟踪进程作为分离的子进程运行,而不是作为父进程运行 |
-f | 跟踪参数 | 跟着叉子走 |
-ff | 跟踪参数 | 跟随分叉,输出到单独的文件中 |
-I interruptible | 跟踪参数 | 可中断信号 1: 没有信号被阻塞 2: 解码系统调用时阻止致命信号(默认) 3: 致命信号始终被阻止(默认情况下为“-o FILE PROG”) 4: 致命信号和SIGTSTP(^Z)始终被阻止 |
-E var | 启动参数 | 从命令的环境中删除var |
-E var=val | 启动参数 | 将var=val放在命令的环境中 |
-p pid | 启动参数 | id为pid的pid跟踪进程,可以重复 |
-u username | 启动参数 | 处理setuid和/或setgid的用户名运行命令 |
-d | 启用调试输出到stderr | |
-v | 详细模式:打印未修改的argv、stat、termios等参数 | |
-h | 打印帮助信息 | |
-V | 打印版本信息 | |
-d | 其他参数 | 启用调试输出到stderr |
-v | 其他参数 | 详细模式:打印未修改的argv、stat、termios等参数 |
-h | 其他参数 | 打印帮助信息 |
-V | 其他参数 | 打印版本信息 |