当前位置: 首页 > java >正文

【操作系统】strace 跟踪系统调用(一)

目录

  • strace 使用指南
    • 一、基本使用
    • 二、系统调用简介
    • 三、strace 的两种使用方式
      • 1. 跟踪即将启动的进程
      • 2. 跟踪已启动的进程
    • 四、strace 常见参数介绍
      • 1.参数说明
      • 2.跟踪某一类系统调用
      • 3.其他跟踪工具
    • 五、strace 输出详细解读
      • 1.输出标准格式
      • 2.示例输出解析
      • 3.ps 命令典型流程
    • 字段含义汇总
    • 系统调用说明


strace 使用指南

strace 是一个非常有用的诊断、调试和教学工具,用于 Linux 系统。它能够跟踪程序执行过程中所进行的系统调用(system calls)以及程序接收到的信号(signals)。通过使用 strace,你可以监控你的应用程序与操作系统内核之间的交互细节,这对于分析程序行为、找出性能瓶颈或定位错误非常有帮助。


一、基本使用

最基本的使用方式是直接跟上你想追踪的命令。例如,要查看 ls 命令执行时的系统调用,你可以运行:

strace ls

这将输出大量的信息到终端,包括每个系统调用的名称、参数和返回值。

如果你只对特定类型的系统调用感兴趣,可以使用 -e 选项来过滤它们。例如,只关注文件打开操作,你可以这样指定:

strace -e open ls

常用选项

  • -p PID:附加到一个已经运行的进程,PID 是该进程的进程ID。
  • -o filename:将输出重定向到一个文件中,方便之后查看。
    • 示例:strace -o ps_trace.log ps
  • -t-tt-ttt:在每行输出前加上时间戳。-tt 提供更精确的时间格式。
  • -f:除了跟踪初始进程外,还要跟踪其 fork 出来的子进程。
  • -c:统计每个系统调用的花费时间、次数和错误数,并给出总结报告。

当你运行带有 strace 的命令时,你会看到类似如下的输出:

open("file.txt", O_RDONLY)              = 3
read(3, "This is a test file.\n", 4096) = 21
close(3)                                         = 0

每一行显示了一个系统调用的信息,包含系统调用的名称、传给它的参数、以及系统调用的返回值。如果发生错误,你还会看到相应的错误消息。


二、系统调用简介

在计算机中,系统调用(System Call) 指运行在用户空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。关联文章: 【操作系统】 Linux 系统调用(一)

操作系统的进程空间分为:

  • 用户空间:通过 API 请求内核空间的服务。
  • 内核空间:直接运行在硬件上,提供设备管理、内存管理、任务调度等功能。

Linux 内核目前有 300 多个系统调用,详细的列表可以通过 syscalls 手册页查看。这些系统调用主要分为几类:

分类示例系统调用
文件和设备访问open, close, read, write, chmod
进程管理fork, clone, execve, exit, getpid
信号处理signal, sigaction, kill
内存管理brk, mmap, mlock
进程间通信 (IPC)shmget, semget, msgget
网络通信socket, connect, sendto, sendmsg
其他

熟悉 Linux 系统调用/系统编程,能够让我们在使用 strace 时得心应手。对于运维的问题定位来说,会使用 strace 这个工具,会查系统调用手册,足够应对大多数场景。


三、strace 的两种使用方式

1. 跟踪即将启动的进程

通过 strace 启动要跟踪的进程,用法是在原有的命令前面加上 strace 即可。

示例:

strace -o ps_trace.log ps
cat ps_trace.log

在这里插入图片描述
在这里插入图片描述

这里可以看出 ps 命令本质是不断读取 /proc/<pid> 下面的信息并展示。

2. 跟踪已启动的进程

通过 -p 参数传递正在运行的进程的 PID 来跟踪。

示例:

strace -p 27256 -o ssh_strace.log

在这里插入图片描述

完成后使用 Ctrl+C 结束跟踪。


四、strace 常见参数介绍

示例命令:

strace -tt -T -v -f -e trace=file -o /data/log/strace.log -s 1024 -p 23489

1.参数说明

参数说明
-tt显示毫秒级别的时间
-T显示每次系统调用所花费的时间
-v输出完整的环境变量、文件 stat 结构等
-f跟踪目标进程及其创建的所有子进程
-e控制要跟踪的事件和行为
-o把输出写入指定的文件
-s最多输出字符串参数长度,默认是 32 字节
-p指定要跟踪的进程 PID

2.跟踪某一类系统调用

类别参数说明
文件相关-e trace=file包括 open, read, write
进程管理-e trace=process包括 fork, exec, exit
网络通信-e trace=network包括 socket, connect
信号处理-e trace=signal包括 kill, sigaction
文件描述符-e trace=desc包括 select, epoll_wait
进程间通信-e trace=ipc包括 shmget, semget

3.其他跟踪工具

  • ltrace:跟踪动态库函数调用(如 printf, malloc)。
  • perf:更高效的系统级性能分析。
  • bpftrace:基于 eBPF 的高级跟踪工具。

五、strace 输出详细解读

命令示例:

strace -o ps_strace.log ps -auxww

1.输出标准格式

syscall_name(arguments...) = return_value

2.示例输出解析

execve("/usr/bin/ps", ["ps", "-auxww"], 0x7ffc0957e898 /* 21 vars */) = 0

execve 执行函数,执行 ps 命令,参数 -auxww,环境变量指针地址,21 个环境变量,返回值为 0 表示成功。

brk(NULL) = 0x18e7000

获取当前堆空间结束地址,返回具体地址 0x18e7000

mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbda92a4000

映射一块匿名内存区域(大小为 4KB),可读写。

access("/etc/ld.so.preload", R_OK) = -1 ENOENT (没有那个文件或目录)

检查文件是否存在,是否可读。返回值 -1 ENOENT 表示文件不存在。

open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

打开 /etc/ld.so.cache 文件,只读方式,设置 FD_CLOEXEC 标志,返回文件描述符 3。

fstat(3, {st_mode=S_IFREG|0644, st_size=28128, ...}) = 0

获取文件状态信息,成功返回 0。

mmap(NULL, 28128, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fbda929d000

/etc/ld.so.cache 映射到内存中进行读取。

close(3) = 0

关闭文件描述符 3,释放资源。

munmap(0x7fbda922b000, 4096) = 0

解除地址 0x7fbda922b000 开始的一块大小为 4096 字节的内存映射。释放之前通过 mmap() 分配的内存区域。

stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=556, ...}) = 0

获取 /etc/localtime 的元数据(比如权限、大小等),ps 显示时间时需要知道本地时区设置。

write(1, "root         1  0.0  0.1 125632 "..., 133) = 133

将一行 ps 输出写入标准输出(文件描述符 1),长度为 133 字节。

假设输出如下:

root         1  0.0  0.1 125632 5584 ?        Ss   15:20   0:00 /sbin/init
stat("/proc/2", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0

获取 /proc/2 目录的状态信息,ps 会遍历 /proc 下的所有数字(PID)目录,并通过此方式判断是否是合法的进程目录。

open("/proc/2/stat", O_RDONLY) = 6

以只读方式打开 /proc/2/stat 文件,获得文件描述符 6,该文件包含进程详细状态信息,如状态、优先级、父进程号等。

read(6, "2 (kthreadd) S 0 0 0 0 -1 213817"..., 2048) = 169

从文件描述符 6 中读取最多 2048 字节的数据,实际读取了 169 字节。

close(6) = 0

关闭文件描述符 6,释放资源。

open("/proc/2/status", O_RDONLY) = 6

打开 /proc/2/status 文件,用于读取更可读的进程状态信息。

read(6, "Name:\tkthreadd\nUmask:\t0000\nState"..., 2048) = 895

/proc/2/status 文件中读取 895 字节的内容。

close(6) = 0

关闭文件描述符 6,释放资源。

open("/proc/2/cmdline", O_RDONLY) = 6

打开 /proc/2/cmdline 文件,查看进程启动命令行参数。

read(6, "", 131072) = 0

/proc/2/cmdline 中读取内容,结果为空,表示没有命令行参数或已到达文件末尾。

close(6) = 0

关闭文件描述符 6,完成清理。


3.ps 命令典型流程

  1. 遍历 /proc 下的数字目录(每个目录名是一个 PID)。
  2. 对每个 PID 执行以下操作:
    • 使用 stat() 检查是否是有效进程目录。
    • 打开并读取 /proc/PID/stat:获取进程状态、CPU 使用率等。
    • 打开并读取 /proc/PID/status:获取更详细的进程信息。
    • 打开并读取 /proc/PID/cmdline:获取命令行参数。
  3. 根据读取的信息构建输出字符串。
  4. 使用 write() 将格式化后的进程信息写入标准输出。

字段含义汇总

字段含义
syscall_name()系统调用名称及参数
arguments参数内容,可能包括文件名、标志位、地址等
return_value返回值,可能是成功状态、资源句柄或错误码
PROT_READ内存保护标志(可读)
PROT_WRITE内存保护标志(可写)
MAP_PRIVATEmmap 的映射类型
MAP_ANONYMOUS匿名映射
O_RDONLY文件打开标志(只读)
O_CLOEXEC关闭时自动释放

系统调用说明

系统调用参数说明作用说明
execveexecve(const char *filename, char *const argv[], char *const envp[])执行一个新程序
openopen(const char *pathname, int flags, mode_t mode)打开或创建一个文件
readread(int fd, void *buf, size_t count)从文件描述符读取数据
writewrite(int fd, const void *buf, size_t count)向文件描述符写入数据
closeclose(int fd)关闭一个打开的文件描述符
mmapmmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)内存映射文件或设备
fstatfstat(int fd, struct stat *statbuf)获取文件状态信息
brkbrk(void *addr)设置进程数据段的结束地址(堆空间)
mprotectmprotect(void *addr, size_t len, int prot)修改内存区域的访问权限
munmapmunmap(void *addr, size_t length)解除内存映射
statstat(const char *path, struct stat *statbuf)获取文件或目录的状态信息

by 久违

http://www.xdnf.cn/news/15330.html

相关文章:

  • 删除screen会话以及查看进程信息的方法
  • DAY02:【ML 第一弹】KNN算法
  • Vue3 实现文件上传功能
  • 完整 Spring Boot + Vue 登录系统
  • EtherCAT开源主站 SOEM 2.0 最新源码在嵌入式 Linux 下的移植与编译
  • 【读书笔记】《C++ Software Design》第九章:The Decorator Design Pattern
  • LeetCode 1156.单字符重复子串的最大长度
  • 代码部落 20250713 CSP-J复赛 模拟赛
  • 婚后才明白,原来结婚真需要一点冲动!
  • 时序预测 | Matlab代码实现VMD-TCN-GRU-MATT变分模态分解时间卷积门控循环单元多头注意力多变量时序预测
  • (一)SAP Group Reporting (GR) 集团财务合并解决方案套件概述
  • java 基本数据类型所对应的包装类
  • 暑期自学嵌入式——Day01(C语言阶段)
  • C++中顶层const与底层const
  • 【开源项目】网络诊断告别命令行!NetSonar:开源多协议网络诊断利器
  • 【研报复现】开源证券:均线的收敛与发散
  • 从 Manifest V2 升级到 Manifest V3:常见问题与解决方案
  • exe文件图标修改器 - exe图标提取器(ico、png) - 修改360文件夹的图标为windows自带的图标
  • # 通过wifi共享打印机只有手动翻页正反打印没有自动翻页正反打印,而通过网线连接的主机电脑可以自动翻页正反打印
  • 设计模式:软件开发的高效解决方案(单例、工厂、适配器、代理)
  • 预处理器完整功能介绍和示例演示(LESS/SCSS)
  • DMDIS文件到数据库
  • 并查集 UnionFind Test01
  • 什么是RAG(Retrieval-Augmented Generation)?一文读懂检索增强生成
  • websocket连接时发生未知错误
  • SAP顾问职位汇总(第28周)
  • 快速生成 Android 的 Splash 的 9 Patch 图片
  • phpMyAdmin:一款经典的MySQL在线管理工具又回来了
  • DNS解析过程和nmap端口扫描
  • 【STM32实践篇】:F407 时钟系统