四、Linux系统调用跟踪工具strace

4.1、strace(系统调用跟踪)

strace 是 Linux 下的系统调用跟踪工具,可以监视进程执行时与内核的交互,包括文件操作、进程管理、网络通信、内存分配等。它主要用于调试、性能优化、问题排查

1. 基本用法

1.1、直接运行程序
strace ./my_program

作用

  • 追踪 my_program 进程的所有系统调用,并在终端输出详细的执行过程。

示例:

strace ls

部分输出

execve("/bin/ls", ["ls"], 0x7ffd12d4) = 0
brk(NULL) = 0x55c3
openat(AT_FDCWD, ".", O_RDONLY|O_DIRECTORY) = 3
read(3, "file1\nfile2\n", 1024) = 12
close(3) = 0
write(1, "file1  file2\n", 14) = 14
exit_group(0) = ?

解释:

  • execve():执行 ls 程序。
  • openat():打开当前目录 (.) 以读取文件列表。
  • read():读取目录内容。
  • write():输出 file1 file2 到终端。

1.2、将输出保存到文件
strace -o trace_log.txt ./my_program

作用:

  • -o trace_log.txt:将 strace 结果保存到 trace_log.txt,不会在终端显示。

示例:

strace -o output.log ls
  • output.log 文件内包含 ls 的所有系统调用。

1.3、跟踪子进程
strace -f ./my_program

作用:

  • -f:跟踪 my_program 及其所有子进程的系统调用。

示例:

strace -f bash -c "ls"
  • bash -c "ls" 会创建子进程 ls-f 确保 ls 也被跟踪。

1.4、显示时间戳
strace -t ./my_program

作用:

  • -t:在每行前面加上时间戳,显示每个系统调用的执行时间。

示例:

strace -t ls

输出:

12:30:01 execve("/bin/ls", ["ls"], 0x7ffd12d4) = 0
12:30:01 openat(AT_FDCWD, ".", O_RDONLY|O_DIRECTORY) = 3
12:30:01 read(3, "file1\nfile2\n", 1024) = 12
12:30:01 write(1, "file1  file2\n", 14) = 14

1.5、只跟踪特定类型的系统调用
1.5.1、仅跟踪文件操作
strace -e open,read,write,close ./my_program

作用:

  • -e open,read,write,close:只显示 open()read()write()close() 相关的系统调用。

示例:

strace -e open,read,write,close ls

输出:

openat(AT_FDCWD, ".", O_RDONLY|O_DIRECTORY) = 3
read(3, "file1\nfile2\n", 1024) = 12
write(1, "file1  file2\n", 14) = 14
close(3) = 0
1.5.2、仅跟踪网络相关调用
strace -e trace=network ./my_program
  • trace=network:仅跟踪 socket()connect()send()recv() 等网络调用。

1.6、统计系统调用次数
strace -c ./my_program

作用:

  • -c 选项只显示系统调用的统计信息,而不是详细日志。

示例:

strace -c ls

输出:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 85.71    0.002156        1234        10           openat
 14.29    0.000358         179         2           write
  0.00    0.000000           0         1           close
------ ----------- ----------- --------- --------- ----------------
100.00    0.002514                    13           total

解释:

  • openat 调用了 10 次,占 85.71% 的执行时间。
  • write 只调用了 2 次,但占 14.29% 的执行时间。
  • close 只调用了 1 次,占比几乎为 0。

1.7、追踪某个已经运行的进程
strace -p 1234

作用:

  • -p 1234:跟踪 PID 为 1234 的进程。

示例:

strace -p $(pgrep nginx)
  • 监控 nginx 进程的所有系统调用。

2、关键系统调用解析

2.1、execve()
execve("./panorama", ["./panorama"], 0x7ffc12c4) = 0
  • execve() 是进程执行的核心系统调用,表示 panorama 被执行。
2.2、open() / openat()
open("/usr/lib/libgstvideo-1.0.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
  • 进程尝试打开 libgstvideo-1.0.so.0,但文件不存在(ENOENT)。

  • 可能的解决方案:

    apt install libgstreamer1.0-dev
    
2.3、read() / write()
read(3, "file1\nfile2\n", 1024) = 12
write(1, "file1  file2\n", 14) = 14
  • read():读取数据到缓冲区。
  • write():将数据输出到终端 (fd=1 代表 stdout)。
2.4、mmap()
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Out of memory)
  • ENOMEM 表示内存不足,可能导致程序崩溃。

2.5、socket() / connect()
socket(AF_INET, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(443), sin_addr=...}, 16) = -1 ECONNREFUSED (Connection refused)
  • ECONNREFUSED:连接被拒绝,可能是网络问题服务器未运行

3、 解决常见问题

错误信息 可能原因 解决方案
ENOENT (No such file) 文件不存在 检查路径,安装缺失的依赖
EACCES (Permission denied) 权限不足 chmodsudo 运行
ENOMEM (Out of memory) 内存不足 增加 swap,关闭无关进程
ECONNREFUSED 连接被拒绝 检查服务器是否运行
posted @ 2025-05-27 10:04  暮云星影  阅读(236)  评论(0)    收藏  举报