magic-trace collects and displays high-resolution traces of what a process is doing
magic-trace
概览
magic-trace 用于收集和显示进程执行的超高分辨率跟踪。人们用它来:
- 弄清楚为什么生产环境中运行的应用程序处理某些请求缓慢,同时却快速处理了大量不感兴趣的请求,
- 查看代码实际执行的操作,而不是人们认为它应该执行的操作,
- 在应用程序崩溃前获取其执行历史,而不仅仅是在那一刻的堆栈跟踪,
- 以及许多其他用途!
magic-trace 的特点:
- 具有 2%-10% 的开销,
- 使用时无需更改应用程序,
- 以大约 40ns 的分辨率跟踪 每个函数调用,
- 渲染一个回溯(可配置的)大约 10ms 的调用栈时间线。
它的使用方式类似于 perf:指向一个进程,然后开始工作。与 perf 的关键区别在于,magic-trace 不是在时间过程中采样调用栈,而是使用 Intel Processor Trace 来快照到选定时间点之前 所有控制流 的环形缓冲区。然后,您可以探索发生了什么的交互式时间线。
您可以将 magic-trace 指向一个函数,当应用程序调用它时,magic-trace 会进行快照。或者,将其附加到正在运行的进程上,然后按 Ctrl+C 来分离,以查看程序中任意点的跟踪。
[^1]:perf 也可以做这个,但大多数人并不这么使用它。实际上,如果您深入了解底层,您会看到 magic-trace 使用 perf 来驱动 Intel PT。
用户评价
"Magic-trace 是我所用过的最简单的命令行调试工具之一。"
- Francis Ricci,Jane Street
"Magic-trace 不仅仅用于性能分析。该工具能直接洞察程序在何时以及为什么发生某些事情。考虑将它用于所有内省目标!"
- Andrew Hunter,Jane Street
我经常使用
perf,我认为perf和 magic-trace 互相补充。我从 magic-trace 获得的收益完全基于它能在任何缩放级别上以切片方式工作,所以我能够看到 70ns 函数执行的所有函数调用,这在perf中是看不到的。
- Doug Patti,Jane Street
安装
-
确保您想要跟踪的系统 受支持。通常困扰人们的限制有:大多数虚拟机不受支持,仅支持 Intel(Skylake[^3] 或更高版本),仅支持 Linux。
-
从 最新发布页面 获取一个发布二进制文件。
- 如果下载的是预构建的二进制文件(非包),则执行
chmod +x magic-trace[^4]。 - 如果下载的是包,则运行
sudo dpkg -i magic-trace*.deb。
然后,通过运行
magic-trace -help来测试它,应该会显示一些帮助文本。 - 如果下载的是预构建的二进制文件(非包),则执行
[^3]:严格来说,是比 Broadwell 更新的任何版本,但我们并不经常在这个平台上测试,且时间分辨率更差(大约 1us)。 [^4]:https://github.com/actions/upload-artifact/issues/38
快速入门
-
这里提供了一个 示例 C 程序 供您尝试。这是
man 3 dlopen示例的略微修改版本。下载该程序,使用gcc demo.c -ldl -o demo进行编译,然后运行./demo保持它运行。我们将使用这个程序来学习dlopen的工作原理。 -
运行
magic-trace attach -pid $(pidof demo)。当您看到它成功附加的消息后,等待几秒钟,然后按 Ctrl+C 终止magic-trace。它将在您的工作目录中输出一个名为trace.fxt.gz的文件。
- 打开 magic-trace.org,在左上角点击 "Open trace file" 并选择上一步生成的跟踪文件。
- 应该会展开跟踪。放大直到您能看到
dlopen/dlsym/cos/printf/dlclose的单个循环。- 按 W 键会放大鼠标指针所指的位置(您需要放大很多才能看到有用的内容),
- 按 S 键会缩小,
- 按 A 键会向左移动,
- 按 D 键会向右移动,且
- 滚轮可以上下移动视图栈。您可能只需要滚动来查看特别深的堆栈跟踪,对于这个示例可能不太有用。
- 在调用栈周围的空白区域单击并拖动以进行测量。在时间线上方单击以设置标记。使用测量工具测量运行
cos的时间。在我的屏幕上,它大约需要 5.7us。
恭喜,您刚刚成功跟踪了您的第一个程序!
与传统的 perf 工作流程相比,magic-trace 在假设生成方面表现出色。例如,您可能会注意到运行 cos 需要 6us 是一段非常长的时间!如果您进一步放大,您会看到实际上有五个粉红色的 "[未跟踪]" 单元。如果您以 root 用户重新运行 magic-trace 并传递 -trace-include-kernel,您将看到这些堆栈跟踪。它们是页面错误处理程序!演示程序实际上调用了两次 cos。如果您在 6us 的 cos 调用的末尾进一步放大,您会看到第二次调用的时间要短得多,并且没有页面错误。
使用方法
magic-trace 持续将控制流记录到环形缓冲区中。在某种触发下,它会对该缓冲区进行快照并重建调用栈。
有两种方式进行快照:
我们刚刚做了这个:按 Ctrl+C 终止 magic-trace。如果 magic-trace 在终止前尚未进行快照,它会拍摄程序的末尾快照。
您还可以在应用程序调用函数时触发快照。为此,传递 -trigger 标志给 magic-trace。
-trigger '?'会弹出一个模糊查找选择器,让您从可执行文件中的所有符号中进行选择,-trigger SYMBOL会选择一个您提前知道的特定、完全混淆的符号,且-trigger .会选择默认符号magic_trace_stop_indicator。
停止指示符非常强大。以下是一些您可能想要放置它们的位置:
- 如果您使用的是异步运行时,任何时候调度器周期耗时过长。
- 在服务器中,当一个请求耗时异常长时。
- 在垃圾收集器运行后,以查看它在做什么以及它中断了什么。
- 在编译器通过后。
您可以将停止指示符留在生产代码中。它不需要执行任何特定操作,magic-trace 只需要这个名称。它是一个空的但不内联的函数。当 magic-trace 实际使用它来拍摄快照时,调用它的开销大约为 10us。
文档
更多文档可在 magic-trace 维基 上找到。
讨论区
欢迎加入我们的 Discord 进行实时交流,或加入 GitHub 讨论组 进行异步讨论。
贡献指南
若您希望贡献力量:
隐私政策
magic-trace 不会将您的代码或代码的派生内容(包括追踪数据)发送到任何地方。
magic-trace.org 是基于 Perfetto 的轻微修改版本,并在您的浏览器中完全运行。据我们所知,它不会将您的追踪数据发送到任何地方。如果您担心未来可能发生变化,可以 设置自己的 Perfetto UI 本地副本 以代替使用。
鸣谢
Tristan Hume 是 magic-trace 的原始作者。他在 Jane Street 工作期间开发了这款工具,该公司目前负责维护。
Intel PT 是 magic-trace 所依赖的基础技术。我们感谢英特尔公司的员工多年来的努力使其得以面世,尽管在更广泛的软件社区中采用率较低。
如果没有 perf 对 Intel PT 的广泛支持,magic-trace 将无法实现。perf 在解释 Intel PT 输出方面做了大部分工作,如果没有他们的努力,magic-trace 可能就不会存在。感谢 perf 开发者们。
magic-trace.org 是 Perfetto 的一个分支,进行了少量修改。我们感谢负责该项目的谷歌公司的员工。这是一个高质量的代码库,出色地解决了一个难题。
magic-trace 背后的想法并非独一无二。我们记录了一份 前期作品 清单,这些作品影响了其设计。
下载使用量
项目总下载次数(含Clone、Pull、 zip 包及 release 下载),每日凌晨更新