这是一个名为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) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。