目录
- 1. Linux strace
- 2. Linux 之 strace 使用技巧
- 2.1. 追踪 linux 系统调用
- 2.2. 只追踪特定的系统调用
- 2.2.1. 过滤指定系统调用
- 2.2.2. 针对进行管理的追踪
- 2.2.3. 针对文件系统调用的追踪
- 2.2.4. 针对内存的追踪
- 2.2.5. 针对网络的追踪
- 2.2.6. 针对信号的追踪
- 2.3. 根据进程 PID 进行追踪
- 2.4. 得到进程的汇总信息
- 2.5. 打印指令指针
- 2.6. 显示调用时间
- 2.7. 显示系统调用的耗时
- 2.8. 将追踪结果写入到文件
- 2.9. 显示 strace 的 debug 信息
- 3. Linux 之 strace/ltrace 使用
- 3.1. strace
- 3.2. ltrace
- 4. Linux 之 strace 调试用法
1. Linux strace
2. Linux 之 strace 使用技巧
# apt install strace
2.1. 追踪 linux 系统调用
只要在原本命令的前面, 加上 strace 关键字, 我们就可以看到原本要执行的这个命令到底做了什么, 下面就是一个追踪 df 命令的例子:
$ strace df -h
结果非常容易理解, 可以看到, 每一行都是一个系统调用, 比如:
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
其中:
- open: 系统调用名
- (“/etc/ld.so.cache”, O_RDONLY|O_CLOEXEC) : 系统调用的参数
- 3: 系统调用的返回结果
2.2. 只追踪特定的系统调用
上述 df -h 的 strace 结果是非常多的, 从中比较难以找到我们真正关心的调用, 通过 -e trace 参数, 通过传入不同的参数值, 就可以过滤出想要的结果了。
2.2.1. 过滤指定系统调用
通过传入系统调用的名称, 就可以只查看对应的系统调用了。
strace -e trace=write df -h
除此以外, 你还可以传入:
- strace -e trace=open,close df -h
- strace -e trace=open,close,read,write df -h
- strace -e trace=all df -h
2.2.2. 针对进行管理的追踪
strace -q -e trace=process df -h
2.2.3. 针对文件系统调用的追踪
strace -q -e trace=file df -h
2.2.4. 针对内存的追踪
strace -q -e trace=memory df -h
2.2.5. 针对网络的追踪
strace -e trace=network df -h
2.2.6. 针对信号的追踪
strace -e trace=signal df -h
2.3. 根据进程 PID 进行追踪
如果一个进程已经在运行, 你可以通过它的 pid 进行追踪, 它会显示追踪后这个进程的系统调用。
strace -p 3569
2.4. 得到进程的汇总信息
使用-c 参数, 可以得到追踪的每一种系统调用的耗时、次数和失败数。
strace -c -p 3569
2.5. 打印指令指针
-i 可以显示每一次系统调用的时候的指令指针
strace -i df -h
2.6. 显示调用时间
-t 参数可以显示调用时间。
strace -t df -h
2.7. 显示系统调用的耗时
-T 参数可以显示系统调用的耗时时间。
strace -T df -h
2.8. 将追踪结果写入到文件
-o 参数将标准输出写入到文件
strace -o df_debug.txt df -h
2.9. 显示 strace 的 debug 信息
-d 可以显示 strace 的 debug 信息。
strace -d df -h
3. Linux 之 strace/ltrace 使用
3.1. strace
strace ./test
ps aux | grep test
1045
strace -s 500 -p 1045
示例: 打印执行 ls 时跟文件有关的系统调用。
strace -e trace=file ls
-e trace=process
跟踪涉及过程管理的所有系统调用。这对于观察进程的派生, 等待和执行步骤很有用。
-e trace=network
跟踪所有与网络相关的系统调用。
-e trace=signal
跟踪所有与信号相关的系统调用。
-e trace=ipc
跟踪所有与 IPC 相关的系统调用。
-o 文件名
将跟踪输出写入文件名而不是 stderr。
-p pid
使用进程 ID pid 附加到该进程并开始跟踪。跟踪可以随时通过键盘中断信号 (CTRL -C) 终止。
-S
按指定条件对-c 选项打印的直方图输出进行排序。
示例: 打印执行 uname 系统调用中 calls 的次数排序
strace -fc -S calls uname
3.2. ltrace
1.ltrace 查看调用耗时
ltrace -c ./a.out
n = 0
% time seconds usecs/call calls function
100.00 0.000157 157 1 printf
100.00 0.000157 1 total
2.strace 查看调用耗时
strace -c ./a.out
n = 0
% time seconds usecs/call calls errors syscall
21.20 0.000085 17 5 mmap
18.70 0.000075 19 4 mprotect
13.47 0.000054 18 3 close
8.73 0.000035 9 4 fstat
8.48 0.000034 11 3 openat
8.23 0.000033 33 1 munmap
6.23 0.000025 8 3 brk
5.24 0.000021 21 1 write
3.74 0.000015 5 3 access
3.24 0.000013 13 1 read
2.74 0.000011 11 1 arch_prctl
0.00 0.000000 0 1 execve
100.00 0.000401 30 total
- 跟踪进程
ltrace -p 11206
4. Linux 之 strace 调试用法
1. 查看函数系统调用
例子: test.c
#include <stdio.h>int main(){printf("Test strace!!!\n");}# gcc test.c -o test
# strace ./test
//打印
execve("./test.c", ["./test.c"], 0x7ffffc5f4820 /* 19 vars */) = -1 EACCES (Permission denied)
fstat(2, {st_mode=S_IFCHR|0660, st_rdev=makedev(4, 3), ...}) = 0
ioctl(2, TCGETS, {B38400 opost isig icanon echo ...}) = 0
write(2, "strace: exec: Permission denied\n", 32strace: exec: Permission denied
) = 32
getpid() = 23900
exit_group(1) = ?
+++ exited with 1 +++2. 查看某个进程系统做了什么
# strace -p 209203. 查看为什么连接不到服务器
# strace -e poll,select,connect,recvfrom,sendto nc www.bing.com 80