proctrace - 一个用于进程生命周期事件的高级分析器

这是一个名为proctrace的剖析器的介绍,它基于bpftrace运行,用于跟踪用户提供命令的进程树的执行,目前记录以下事件及它们之间的时间:forkexecexitsetsidsetpgid,未来计划扩展到跟踪文件描述符的打开/关闭/继承以及读写操作。

proctrace的相关内容如下:

  • 发布信息:发布于 2024 年 9 月 9 日,在GitHub上有仓库,文档网站有使用说明,将参加 RustConf 2024 会议。
  • 问题背景:作者在Flox工作,开发了proctrace来解决服务管理中的测试问题,如bats测试套件中的竞态条件导致的测试不稳定,以及难以识别测试中泄漏的后台进程等问题。
  • 设计阶段

    • 需求:给定一个 PID,能够跟踪其通过forkexecexitsetpgidsetsid创建新进程、执行新程序、终止、更改与其他进程的关系以及其后代进程的上述操作,并以“有用”的方式呈现这些信息。
    • 接口:有“记录所有事件”和“为用户执行并过滤事件”两种接口,默认模式为后者。
    • 事件源:选择bpftrace作为事件收集工具,由于 macOS 系统的一个 bug,目前仅支持bpftrace,记录所有进程的事件,由外部工具proctrace进行处理。
    • 终止:当进程树中的所有进程都退出时停止记录,目前proctrace不会杀死仍在运行的进程,但有一个未解决的问题将来会实现。
  • 使用方法

    • 创建记录:proctrace record -o <file> -- <cmd>,会调用bpftrace并提示输入密码,记录的事件以换行分隔的 JSON 格式存储在指定文件中。
    • 渲染记录:有默认的sequential渲染方法和by-process渲染方法,前者按事件发生顺序显示,后者按进程分组显示,还可以将原始记录转换为可渲染的记录。
  • 实现挑战

    • 记录进程与线程:需要确保探针过滤掉线程事件,通过检查$task->pid == $task->tgid来确定是否为进程事件。
    • 重复fork:通过直接监测clone系统调用并检查标志来确定是创建线程还是进程,同时使用两个clone探针来处理clone系统调用的多次返回。
    • 缓冲:proctrace在摄入bpftrace的事件时使用两个事件存储,一个用于“跟踪”事件,一个用于“缓冲”事件,以应对forkexec可能出现的顺序问题,目前缓冲区未进行垃圾回收。
    • exec参数:bpftrace存在打印exec参数的 bug,作者通过查询/proc来获取参数,但存在参数不一致的问题,目前使用较长的参数集。
    • 重复exec:可能是bpftrace脚本未正确过滤线程导致的,在示例脚本中可能遗漏了某些exec事件。
    • Mermaid 限制:Mermaid 不支持包含冒号的命令渲染图表,也不支持任意时间尺度,目前使用毫秒作为时间单位,并对执行时间进行四舍五入。
  • 未来展望:希望生成类似 Cargo 的 HTML 报告,更准确、灵活地显示信息,如根据进程组对跨度进行颜色标记,欢迎大家在Github Issues page上提供改进建议。
阅读 10
0 条评论