RH442之strace和ltrace性能分析
strace、ltrace是Linux环境下的程序调试工具,strace用来监察一个应用程序所使用的系统调用及它所接收的系统信息。追踪程序运行时的整个生命周期,输出每一个系统调用的名字,参数,返回值和执行消耗的时间等。其与ltrace的区别是:strace主要用于跟踪系统调用和信号;ltrace用于跟踪用户级别的函数。
一、strace程序
strace程序常用的参数如下:
1-p 跟踪指定的进程
2-f 跟踪由fork子进程系统调用
3-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
4-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
5-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
6-r 打印每一个系统调用的相对时间
7-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
8-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
9-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
10-c 统计每种系统调用所执行的时间,调用次数,出错次数。
11-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出
对于即将执行的命令,可以通过strace直接跟踪,这里以执行uname命令为例,如下:
1[student@desktop0 ~]$ strace uname
2execve("/bin/uname", ["uname"], [/* 17 vars */]) = 0
3brk(0) = 0x1cfe000
4mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdaca195000
5access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
6open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
7fstat(3, {st_mode=S_IFREG|0644, st_size=67468, ...}) = 0
8mmap(NULL, 67468, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fdaca184000
9close(3) = 0
10open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
11………………略
如果是已经运行的程序,可以通过-p参数查看进程的系统调用:
1[root@desktop0 ~]# strace -p 1135
2Process 1135 attached
3select(7, [3 4], NULL, NULL, NULL
4) = ? ERESTARTNOHAND (To be restarted if no handler)
5--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4164, si_status=255, si_utime=2, si_stime=24} ---
6wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 255}], WNOHANG, NULL) = 4164
7wait4(-1, 0x7fffb3ff5a94, WNOHANG, NULL) = 0
8rt_sigaction(SIGCHLD, NULL, {0x7f172309f080, [], SA_RESTORER, 0x7f1720248a00}, 8) = 0
9rt_sigreturn() = -1 EINTR (Interrupted system call)
10select(7, [3 4], NULL, NULL, NULL) = 1 (in [3])
11accept(3, {sa_family=AF_INET, sin_port=htons(52208), sin_addr=inet_addr("172.25.0.250")}, [16]) = 5
12fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
13pipe([6, 7]) = 0
14…………略
不过这里使用-p参数输出的结果比较少,需要使用-f参数才能捕获fork的进程。使用-c参数能可以统计系统调用:
1[root@desktop0 ~]# strace -c uname
2Linux
3% time seconds usecs/call calls errors syscall
4------ ----------- ----------- --------- --------- ----------------
5 26.88 0.000050 6 9 mmap
6 17.74 0.000033 11 3 open
7 15.05 0.000028 14 2 munmap
8 13.98 0.000026 7 4 mprotect
9 5.38 0.000010 10 1 write
10 4.30 0.000008 2 4 fstat
11 4.30 0.000008 8 1 1 access
12 3.76 0.000007 1 5 close
13 3.76 0.000007 2 4 brk
14 1.61 0.000003 3 1 read
15 1.61 0.000003 3 1 execve
16 1.08 0.000002 2 1 uname
17 0.54 0.000001 1 1 arch_prctl
18------ ----------- ----------- --------- --------- ----------------
19100.00 0.000186 37 1 total
如果需要捕获子进程调用,可以strace -fc配合使用。
二、ltrace程序
ltrace相关的参数如下:
1-a 对齐具体某个列的返回值
2-c 计算时间和调用,并在程序退出时打印摘要
3-C 解码低级别名称(内核级)为用户级名称
4-d 打印调试信息
5-e 改变跟踪的事件
6-f 跟踪子进
7-h 打印帮助信息
8-i 打印指令指针,当库调用时。
9-l 只打印某个库中的调用。
10-L 不打印库调用。
11-n, --indent=NR 对每个调用级别嵌套以NR个空格进行缩进输出。
12-o, --output=file 把输出定向到文件。
13-p PID 附着在值为PID的进程号上进行ltrace。
14-r 打印相对时间戳。
15-s STRLEN 设置打印的字符串最大长度。
16-S 显示系统调用。
17-t, -tt, -ttt 打印绝对时间戳。
18-T 输出每个调用过程的时间开销。
19-u USERNAME 使用某个用户id或组ID来运行命令。
其使用方法如下:
1[root@desktop0 ~]# ltrace uname
2__libc_start_main(0x401490, 1, 0x7fff0fbd9648, 0x4042a0 <unfinished ...>
3strrchr("uname", '/') = nil
4setlocale(LC_ALL, "") = "en_US.UTF-8"
5bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
6textdomain("coreutils") = "coreutils"
7__cxa_atexit(0x401c40, 0, 0, 0x736c6974756572) = 0
8getopt_long(1, 0x7fff0fbd9648, "asnrvmpio", 0x606be0, nil) = -1
9uname(0x7fff0fbd93b0) = 0
10fputs_unlocked(0x7fff0fbd93b0, 0x7fb4b5607400, 0x7fb4b5606280, -1) = 1
11__overflow(0x7fb4b5607400, 10, 0x7fb4b582b004, 1024Linux
12) = 10
13…………略
其统计时间使用方法如下:
1[root@desktop0 ~]# ltrace -c uname
2Linux
3% time seconds usecs/call calls function
4------ ----------- ----------- --------- --------------------
5 44.84 0.008281 8281 1 __libc_start_main
6 23.00 0.004248 4248 1 exit
7 4.19 0.000774 193 4 __freading
8 3.64 0.000673 673 1 setlocale
9 3.03 0.000559 279 2 fflush
10 2.95 0.000545 272 2 fclose
11 2.93 0.000541 541 1 __overflow
12 2.68 0.000494 247 2 fileno
13 2.27 0.000420 210 2 __fpending
14 1.62 0.000300 300 1 bindtextdomain
15 1.55 0.000287 287 1 fputs_unlocked
16 1.51 0.000278 278 1 getopt_long
17 1.44 0.000265 265 1 uname
18 1.28 0.000237 237 1 textdomain
19 1.23 0.000227 227 1 strrchr
20 1.06 0.000196 196 1 __cxa_atexit
21 0.76 0.000141 141 1 exit_group
22------ ----------- ----------- --------- --------------------
23100.00 0.018466 24 total
通过-e进行函数类型匹配调用方法如下:
1[root@desktop0 ~]# ltrace -e fclose -c uname
2Linux
3% time seconds usecs/call calls function
4------ ----------- ----------- --------- --------------------
5 83.61 0.000699 349 2 fclose
6 16.39 0.000137 137 1 exit_group
7------ ----------- ----------- --------- --------------------
8100.00 0.000836 3 total
通过strace、ltrace这类工具的分析,我们可以找出某些程序的性能问题在哪。
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/strace-ltrace/5445.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.