Linux strace命令
strace
是Linux下强大的系统调用跟踪工具,主要用于调试、性能分析、故障排查等。它可以拦截并记录进程执行过程中涉及的系统调用(syscall),帮助开发者和运维人员了解程序的行为。
1. strace基础知识
1.1 什么是strace
strace
通过ptrace
系统调用跟踪并拦截目标进程的所有系统调用,记录参数、返回值、执行时间等信息。例如:
strace ls
运行ls
并显示其执行期间的所有系统调用:
openat(AT_FDCWD, ".", O_RDONLY|O_DIRECTORY) = 3
getdents64(3, /* 3 entries */, 32768) = 80
write(1, "file1\nfile2\n", 12) = 12
close(3) = 0
可以看出:
- openat打开当前目录
- getdents64读取目录内容
- write将内容写到标准输出
1.2 strace使用场景
1. 调试程序
- 发现文件权限错误、缺少库文件、崩溃问题
2. 性能分析
- 统计进程中最耗时的系统调用
3. 监控进程
- 追踪进程执行哪些系统调用、文件访问、网络请求等
4. 故障排查
- 解决"Permission Denied"、"File Not Found"等问题
2. strace常用选项
选项 | 作用 |
---|---|
-p <pid> | 跟踪已运行进程 |
-o file.log | 将输出写入文件 |
-c | 统计系统调用的执行时间、次数 |
-tt | 显示完整时间戳 |
-T | 显示每个系统调用的执行时间 |
-e <expr> | 过滤指定类型的系统调用,如-e open,read |
-f | 跟踪子进程 |
3. strace详细示例
3.1 追踪进程的系统调用
strace ls /etc
示例输出:
openat(AT_FDCWD, "/etc", O_RDONLY|O_DIRECTORY) = 3
getdents64(3, /* 112 entries */, 32768) = 4096
write(1, "file1\nfile2\n", 12) = 12
close(3) = 0
exit_group(0) = ?
3.2 跟踪指定进程
strace -p 1234
如果1234是nginx进程,可以看到:
accept4(4, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.168.1.2")}, [16], SOCK_CLOEXEC) = 5
nginx
在8080
端口接受了来自192.168.1.2
的连接。
3.3 仅跟踪特定类型的系统调用
strace -e openat,read,write ls
只显示openat
、read
、write
调用:
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3
read(3, "root:x:0:0:root:/root:/bin/bash\n", 37) = 37
write(1, "root:x:0:0:root:/root:/bin/bash\n", 37) = 37
3.4 统计进程调用的系统调用
strace -c ls
示例输出:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
40.00 0.000015 5 3 openat
20.00 0.000007 3 2 close
20.00 0.000007 3 2 read
10.00 0.000004 4 1 write
可以看到openat
被调用了3次,占了40%
的执行时间。
3.5 将strace结果写入文件
strace -o output.log ls
然后查看output.log
:
less output.log
3.6 监视进程打开的文件
strace -e openat -p 1234
示例输出:
openat(AT_FDCWD, "/var/log/nginx/access.log", O_RDONLY) = 4
表名进程1234
访问了/var/log/nginx/access.log
。
3.7 监视进程的网络活动
strace -e network -p 1234
示例输出:
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("93.184.216.34")}, 16) = 0
进程创建了一个TCP连接到93.184.216.34:80
。
4. strace高级用法
4.1 过滤错误信息
strace -p 1234 2>&1 | grep -i "enoent\|eaccess\|eperm"
- ENOENT(文件不存在)。
- EACCESS(权限不足)。
- EPERM(操作不允许)。
4.2 监视特定进程的子进程
strace -f -p 1234
示例输出:
[pid 1234] fork() = 5678
[pid 5678] execve("/bin/bash", ["bash"], 0x7ffc12345678 /* 23 vars */) = 0
4.3 监视exec调用
strace -e execve -p 1234
如果1234
运行vim
,输出:
execve("/usr/bin/vim", ["vim"], 0x7ffc12345678) = 0
4.4 结合lsof和strace
lsof -p 1234
strace -p 1234 -e openat,read,write
lsof
列出进程打开的文件strace
监视读写操作
4.5 监视进程的CPU和IO
strace -p 1234 -T
示例:
openat(AT_FDCWD, "/var/log/syslog", O_RDONLY) = 3 <0.001234>
<0.001234>
表示openat
调用了1.2
毫秒。
5. strace总结
strace
是Linux系统调试和性能分析的利器,主要用来:
- 追踪进程调用的系统调用
- 监视文件、网络访问情况
- 排查程序崩溃、权限问题
- 优化系统性能,找出瓶颈