这是一个名为proctrace
的剖析器的介绍,它基于bpftrace
运行,用于跟踪用户提供命令的进程树的执行,目前记录以下事件及它们之间的时间:fork
、exec
、exit
、setsid
、setpgid
,未来计划扩展到跟踪文件描述符的打开/关闭/继承以及读写操作。
proctrace
的相关内容如下:
- 发布信息:发布于 2024 年 9 月 9 日,在GitHub上有仓库,文档网站有使用说明,将参加 RustConf 2024 会议。
- 问题背景:作者在Flox工作,开发了
proctrace
来解决服务管理中的测试问题,如bats
测试套件中的竞态条件导致的测试不稳定,以及难以识别测试中泄漏的后台进程等问题。 设计阶段:
- 需求:给定一个 PID,能够跟踪其通过
fork
、exec
、exit
、setpgid
和setsid
创建新进程、执行新程序、终止、更改与其他进程的关系以及其后代进程的上述操作,并以“有用”的方式呈现这些信息。 - 接口:有“记录所有事件”和“为用户执行并过滤事件”两种接口,默认模式为后者。
- 事件源:选择
bpftrace
作为事件收集工具,由于 macOS 系统的一个 bug,目前仅支持bpftrace
,记录所有进程的事件,由外部工具proctrace
进行处理。 - 终止:当进程树中的所有进程都退出时停止记录,目前
proctrace
不会杀死仍在运行的进程,但有一个未解决的问题将来会实现。
- 需求:给定一个 PID,能够跟踪其通过
使用方法:
- 创建记录:
proctrace record -o <file> -- <cmd>
,会调用bpftrace
并提示输入密码,记录的事件以换行分隔的 JSON 格式存储在指定文件中。 - 渲染记录:有默认的
sequential
渲染方法和by-process
渲染方法,前者按事件发生顺序显示,后者按进程分组显示,还可以将原始记录转换为可渲染的记录。
- 创建记录:
实现挑战:
- 记录进程与线程:需要确保探针过滤掉线程事件,通过检查
$task->pid == $task->tgid
来确定是否为进程事件。 - 重复
fork
:通过直接监测clone
系统调用并检查标志来确定是创建线程还是进程,同时使用两个clone
探针来处理clone
系统调用的多次返回。 - 缓冲:
proctrace
在摄入bpftrace
的事件时使用两个事件存储,一个用于“跟踪”事件,一个用于“缓冲”事件,以应对fork
和exec
可能出现的顺序问题,目前缓冲区未进行垃圾回收。 exec
参数:bpftrace
存在打印exec
参数的 bug,作者通过查询/proc
来获取参数,但存在参数不一致的问题,目前使用较长的参数集。- 重复
exec
:可能是bpftrace
脚本未正确过滤线程导致的,在示例脚本中可能遗漏了某些exec
事件。 - Mermaid 限制:Mermaid 不支持包含冒号的命令渲染图表,也不支持任意时间尺度,目前使用毫秒作为时间单位,并对执行时间进行四舍五入。
- 记录进程与线程:需要确保探针过滤掉线程事件,通过检查
- 未来展望:希望生成类似 Cargo 的 HTML 报告,更准确、灵活地显示信息,如根据进程组对跨度进行颜色标记,欢迎大家在Github Issues page上提供改进建议。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。