Linux教程网

Linux系统性能分析利器strace

strace 可以跟踪一个进程的系统调用和信号,不仅可以帮助开发人员和管理员更好的理解应用程序的行为,还可以帮助开发开发人员调试问题,分析性能。

我们知道,应用程序是不可以直接操作硬件和底层资源。如果要操作底层硬件的话,就需要执行内核提供的系统调用函数,通过 strace 命令可以跟踪程序所有的系统调用,相当于给用户提供一种观测底层资源操作的能力。

安装strace

对于大多数操作系统,都可以通过软件包管理器来进行安装

1. ubuntu

1
apt-get install strace -y

2. centos

1
yum install strace -y

基本用法

1. 基本用法

strace 用法非常简单,我们在要跟踪的程序前面加上 strace 即可

1
2
3
4
5
6
7
8
9
10
11
$ strace ls

# 不完整输出
execve("/usr/bin/ls", ["ls"], 0x7ffe90ebbd00 ) =
brk(NULL) = 0x557eb41b8000
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=27202, ...}) = 0
mmap(NULL, 27202, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fcf011d2000
close(3) = 0
openat(AT_FDCWD, "libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, ""..., 832) = 832

可以看到与 ls 命令相关的系统调用都被打印了出来。= 左侧是系统调用函数名称与参数,右侧是函数调用后的返回值

2. 重定向输出

默认情况下,strace 会把所有的系统调用信息打印到屏幕上,如果信息过多不便于观察分析,可以将信息重定向到文件中

1
2
3
4
strace -o output.txt ls

# 等价于
strace ls &> output.txt

3. 跟踪正在运行的进程

strace 除了可以跟踪一个新启动的程序外,还可以跟踪正在运行的程序。我们需要先获取要跟踪程序的进程 PID

1
strace -p 533880

通过 -p 选项,指定需要跟踪的程序

4. 显示时间

通过 -t 选项,可以在每个系统调用信息前边显示时间戳

1
strace -t ls
  • -t:在输出中的每一行前加上时间信息
  • -tt:在输出中的每一行前加上时间信息,微秒级
  • -ttt:微秒级,以时间戳格式输出

过滤输出

从上边我们知道,strace 会把捕捉到的所有系统调用都打印出来了。而在程序调试分析时,我们往往并不希望看到所有的系统调用,而是指定具体的系统调用。

1. 跟踪指定的系统调用

1
strace -e trace=open,read,close ls

上边的命令只跟踪 openreadclose 相关的系统调用。除了具体的系统调用外,还支持指定如下的方式

  • -e trace=file:只跟踪有关文件操作的系统调用
  • -e trace=process:只跟踪有关进程控制的系统调用
  • -e trace=network:跟踪与网络有关的所有系统调用
  • -e trace=signal:跟踪所有与系统信号有关的系统调用
  • -e trace=ipc:跟踪所有与进程通讯有关的系统调用

2. 只跟踪指定的信号

通过 -e signal 指定要跟踪的信号

1
strace -e signal=SIGIO ls

3. 只跟踪从指定的文件来读数据

1
strace -e read=3,5 myapp

4. 只跟踪从指定的文件来写数据

1
strace -e write=4,6 myapp

统计功能

strace 除了可以提供具体的系统调用信息外,还能提供信息统计功能。它可以统计在一段时间内,每个系统调用的次数时间消耗时间占比错误次数等信息。

这些信息对排查程序问题非常有帮助,它可以告诉你哪个系统调用消耗时间最长,哪个系统调用错误较高,哪个系统调用次数最多,在问题排查时非常有用。

strace 通过 -c 选项就可以这些信息的统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ strace -c ls
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
16.57 0.000029 1 27 mmap
12.00 0.000021 10 2 getdents64
11.43 0.000020 2 7 read
11.43 0.000020 2 8 mprotect
9.14 0.000016 1 9 openat
6.86 0.000012 6 2 2 statfs
6.29 0.000011 1 11 close
5.14 0.000009 9 1 write
4.57 0.000008 8 1 munmap
4.00 0.000007 0 10 fstat
2.86 0.000005 2 2 ioctl
2.29 0.000004 2 2 rt_sigaction
2.29 0.000004 2 2 2 access
1.71 0.000003 1 3 brk
1.14 0.000002 2 1 rt_sigprocmask
0.57 0.000001 0 2 1 arch_prctl
0.57 0.000001 1 1 set_tid_address
0.57 0.000001 1 1 set_robust_list
0.57 0.000001 1 1 prlimit64
0.00 0.000000 0 8 pread64
0.00 0.000000 0 1 execve
------ ----------- ----------- --------- --------- ----------------
100.00 0.000175 102 5 total

在程序执行完毕后,就会输出相应的统计信息。如果你使用 -p 选项,正在跟踪一个正在运行的程序时,统计信息会在你执行 Ctrl + C 之后才会显示出来。

如果想统计每个系统调用的消耗时间,可以通过 -T 选项来实现

1
2
3
4
5
6
7
8
9
$ strace -T -e trace=read ls

read(3, ""..., 832) = 832 <0.000011>
read(3, ""..., 832) = 832 <0.000009>
read(3, ""..., 832) = 832 <0.000011>
read(3, ""..., 832) = 832 <0.000009>
read(3, ""..., 832) = 832 <0.000006>
read(3, ""..., 1024) = 447 <0.000023>
read(3, "", 1024) = 0 <0.000006>

可以看到,系统调用信息后边增加了耗时的统计

常用选项

下边总结一下 strace 的常见选项

-c:统计每一系统调用的所执行的时间,次数和出错的次数等
-d:输出strace关于标准错误的调试信息
-f:跟踪由fork调用所产生的子进程
-F:尝试跟踪vfork调用
-h:输出简要的帮助信息
-i:输出系统调用的入口指针
-q:禁止输出关于脱离的消息
-r:打印出相对时间
-t:在输出中的每一行前加上时间信息
-tt:显示微秒级时间
-ttt:微秒级输出(以秒显示)
-T:显示每一调用所耗的时间
-v:输出所有的系统调用
-V:输出strace的版本信息
-x:以十六进制形式输出非标准字符串
-xx:所有字符串以十六进制形式输出
-a column:设置返回值的输出位置
-e expr:指定一个表达式,用来控制如何跟踪
-e trace=set:只跟踪指定的系统调用
-e trace=file:只跟踪有关文件操作的系统调用
-e trace=process:只跟踪有关进程控制的系统调用
-e trace=network:跟踪与网络有关的所有系统调用
-e strace=signal:跟踪所有与系统信号有关的 系统调用
-e trace=ipc:跟踪所有与进程通讯有关的系统调用
-e abbrev=set:设定strace输出的系统调用的结果集
-e raw=set:将指定的系统调用的参数以十六进制显示
-e signal=set:指定跟踪的系统信号
-e read=set:输出从指定文件中读出的数据
-e write=set:输出写入到指定文件中的数据
-o filename:将strace的输出写入文件filename
-p pid:跟踪指定的进程pid
-s strsize:指定输出的字符串的最大长度
-u username:以username的UID和GID执行被跟踪的命令


专题:

本文发表于 2023-04-05,最后修改于 2023-09-17。

本站永久域名「 golinuxblog.com 」,也可搜索「 Linux教程网 」找到我。


上一篇 « 如何将Vim快捷键带入浏览器 下一篇 » Linux cd 命令详解

推荐阅读

Big Image