Files
wehub-resource-sync 9229e4ca4a
build-deb / build (push) Has been cancelled
build / build (5.2.0+ox, ubuntu_x64_8_cores, 231c88c2e564fdca40e15e750aacad5fb0887435) (push) Has been cancelled
docs: make Chinese README the default
2026-07-13 10:18:10 +00:00

170 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- WEHUB_ZH_README -->
> [!NOTE]
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
> [English](./README.en.md) · [原始项目](https://github.com/janestreet/magic-trace) · [上游 README](https://github.com/janestreet/magic-trace/blob/HEAD/README.md)
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
<h1 align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo-dark.svg?sanitize=true">
<img src="docs/assets/logo-light.svg?sanitize=true" width="150px">
</picture>
<br>
magic-trace
</h1>
<p align="center">
<a href="https://github.com/janestreet/magic-trace/actions?query=workflow%3Abuild" alt="Linux Build Status">
<img src="https://img.shields.io/github/actions/workflow/status/janestreet/magic-trace/build.yml?branch=master&logo=github&style=flat-square"/>
</a>
<a href="https://github.com/janestreet/magic-trace/releases/latest">
<img src="https://img.shields.io/github/v/tag/janestreet/magic-trace?label=version&style=flat-square"/>
</a>
<a href="LICENSE.md">
<img src="https://img.shields.io/github/license/janestreet/magic-trace?style=flat-square"/>
</a>
</p>
# 概述
magic-trace 收集并展示进程正在执行内容的高分辨率追踪(trace)记录。人们用它来:
- 查明为何生产环境中运行的应用在处理某些请求时很慢,同时又在应付海量无趣请求,
- 看清代码*实际*在做什么,而不是*以为*它在做什么,
- 获取应用崩溃前的执行历史,而不只是最后时刻的一张堆栈跟踪(stacktrace),
- ……以及更多用途!
magic-trace
- 具有 [2%-10% 开销](https://github.com/janestreet/magic-trace/wiki/Overhead),
- 使用时不需修改应用,
- 以约 40ns 分辨率追踪*每一次函数调用*,并且
- 渲染可回溯约 10ms(可配置)的调用栈时间线。
用法类似 [`perf`](https://en.wikipedia.org/wiki/Perf_(Linux)): 指向一个进程即可开始运行。与 `perf` 的关键区别在于:magic-trace 不是随时间对调用栈采样,而是使用 [Intel Processor Trace](https://man7.org/linux/man-pages/man1/perf-intel-pt.1.html) 对截至某一选定时刻的*全部控制流*环形缓冲区做快照[^1]。然后你可以交互式地浏览时间线上发生的事。
你可以让 magic-trace 盯住某个函数,这样当应用调用它时,magic-trace 就会拍一张快照。或者附加到正在运行的进程上,用 <kbd>Ctrl</kbd>+<kbd>C</kbd> 分离,以查看程序任意时刻的追踪记录。
[^1]`perf` 也能做到这一点,但多数人并不这么用它。事实上,若深入底层,你会发现 magic-trace 使用 `perf` 来驱动 Intel PT。
# 用户评价
> "Magic-trace 是我用过的最简单的命令行调试工具之一。"
- Francis Ricci, Jane Street
> "Magic-trace 不仅用于性能分析。它能直接揭示程序中发生了什么、何时发生以及为何发生。建议为满足一切自省(introspective)目标时都考虑使用它!"
- Andrew Hunter, Jane Street
> 我经常用 perf,我认为 perf 和 magic-trace 各自提供了对方没有的视角。我从 magic-trace 获益,完全是因为它能在任意缩放级别下按切片展示,因此我能看到某个 70ns 函数执行的所有函数调用,而在 perf 中这些内容完全不可见。
- Doug Patti, Jane Street
[更多用户评价……](https://github.com/janestreet/magic-trace/wiki/Unsolicited-reviews)
# 安装
1. 确保要追踪的系统[受支持](https://github.com/janestreet/magic-trace/wiki/Supported-platforms,-programming-languages,-and-runtimes). 最容易让人栽跟头的限制是:虚拟机大多不受支持、仅支持 Intel(Skylake[^3] 或更新)、仅支持 Linux。
2. 从[最新发布页](https://github.com/janestreet/magic-trace/releases/latest). 获取发布版二进制文件。
1. 若下载的是预编译二进制文件(非软件包),`chmod +x magic-trace`[^4]
1. 若下载的是软件包,运行 `sudo dpkg -i magic-trace*.deb`
然后运行 `magic-trace -help` 进行测试,应会显示一些帮助文本。
[^3]:严格来说,任何比 Broadwell 更新的平台都可以,但我们不会定期在该平台上测试,且时间分辨率更差(约 1us)。
[^4]https://github.com/actions/upload-artifact/issues/38
# 快速入门
1. [这里](https://raw.githubusercontent.com/janestreet/magic-trace/master/demo/demo.c)'s 有一份可供试用的示例 C 程序。它是 `man 3 dlopen` 中示例的轻微修改版。下载后,用 `gcc demo.c -ldl -o demo` 编译,再以 `./demo` 保持运行。我们将用该程序学习 `dlopen` 的用法。
2. 运行 `magic-trace attach -pid $(pidof demo)`。看到已成功附加的提示后,等待几秒,然后对 `magic-trace` 按 <kbd>Ctrl</kbd>+<kbd>C</kbd>。它会在当前工作目录输出名为 `trace.fxt.gz` 的文件。
<p align="center">
<img src="docs/assets/stage-1.gif">
</p>
3. 打开 [magic-trace.org](https://magic-trace.org/), 点击左上角的 _"Open trace file"_(打开追踪文件),并选择上一步生成的追踪文件。
<p align="center">
<img src="docs/assets/stage-2.gif">
</p>
4. 此时应已展开为一条追踪记录。放大直到能看到 `dlopen`/`dlsym`/`cos`/`printf`/`dlclose` 的单次循环。
- <kbd>W</kbd> 向鼠标光标所在位置放大(需要多次放大才能看到有用内容),
- <kbd>S</kbd> 缩小,
- <kbd>A</kbd> 向左移动,
- <kbd>D</kbd> 向右移动,以及
- 滚轮在调用栈上下移动视口。只有查看特别深的堆栈跟踪时才需要滚动,对本示例可能用处不大。
<p align="center">
<img src="docs/assets/stage-3.gif">
</p>
5. 在调用栈周围的空白处点击拖动以进行测量。在时间线顶部点击可插旗标。使用测量工具,测量运行 `cos` 的耗时。在我的屏幕上约为 ~5.7us。
<p align="center">
<img src="docs/assets/stage-4.gif">
</p>
恭喜,你刚刚神奇地完成了第一次程序追踪!
与传统 `perf` 工作流相比,magic-trace 擅长生成假设。例如,你可能会注意到运行 `cos` 耗时 6us 实在太长了!若再放大,你会看到其中实际上有五个粉色的 "\[untraced\]" 单元格。若以 root 重新运行 magic-trace 并传入 `-trace-include-kernel`,就能看到它们的堆栈跟踪。它们是页错误(page fault)处理程序!演示程序实际上调用了 `cos` 两次。若在 6us 的 `cos` 调用末尾附近再放大,你会看到第二次调用耗时*远*更少且不会发生页错误。
# 使用方法
magic-trace 将持续把控制流记录到环形缓冲区。在某种触发条件下,它对缓冲区拍快照并重建调用栈。
有两种拍快照的方式:
我们刚才做的就是其中一种:<kbd>Ctrl</kbd>+<kbd>C</kbd> 结束 magic-trace。若 magic-trace 在未拍过快照的情况下终止,会对程序末尾拍一张快照。
你也可以在应用调用某个函数时触发快照。做法是向 magic-trace 传入 `-trigger` 标志。
- `-trigger '?'` 会弹出模糊查找选择器,让你从可执行文件中的所有符号里选择,
- `-trigger SYMBOL` 选择你事先知道的某个具体、完整修饰(mangled)符号,以及
- `-trigger .` 选择默认符号 `magic_trace_stop_indicator`
停止指示器(stop indicator)很强大。以下是一些你可能想放置它的场景:
- 若使用异步运行时,可在调度器周期耗时过长时放置。
- 在服务器中,当某个请求耗时出奇地长时。
- 垃圾回收器运行之后,查看它在做什么以及它打断了什么。
- 某个编译器 pass 完成之后。
你可以把停止指示器留在生产代码中。它不必执行任何特定操作,magic-trace 只需要函数名。它只是一个空函数,但不会被内联。调用它大约耗费 ~10us,但*仅在 magic-trace 实际用它拍快照时*才会产生该开销。
# 文档
更多文档可在 [magic-trace wiki](https://github.com/janestreet/magic-trace/wiki). 上查阅。
# 讨论
加入我们的 [Discord](https://discord.gg/vkzPYeZ292) 进行实时交流,或前往 [GitHub 讨论组](https://github.com/janestreet/magic-trace/discussions) 进行异步讨论。
# 贡献
如果你想贡献代码:
1. [阅读构建说明](https://github.com/janestreet/magic-trace/wiki/Build-instructions),
1. [配置你的编辑器](https://ocaml.org/learn/tutorials/up_and_running.html#Editor-support-for-OCaml),
1. [快速浏览代码库](https://github.com/janestreet/magic-trace/wiki/A-quick-tour-of-the-codebase),,然后
1. [查看 issue 跟踪器](https://github.com/janestreet/magic-trace/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) 寻找合适的入门项目。
# 隐私政策
magic-trace 不会将你的代码或其衍生内容(包括 traces)发送到任何地方。
[magic-trace.org](https://magic-trace.org) 是 [Perfetto](https://github.com/janestreet/magic-trace/wiki/About-the-UI), 的轻度修改 fork,完全在浏览器中运行。据我们所知,它不会将 trace 发送到任何地方。如果你担心这一点日后可能改变,可以 [搭建本地 Perfetto UI 副本](https://github.com/janestreet/magic-trace/wiki/Setting-up-a-local-copy-of-the-UI) 并使用它。
# 致谢
[Tristan Hume](https://github.com/trishume) 是 magic-trace 的原始作者。他在 [Jane Street](https://www.janestreet.com/join-jane-street/), 工作期间编写了该项目,Jane Street 目前负责维护。
Intel PTIntel Processor Trace)是 magic-trace 所依赖的基础技术。我们要感谢 Intel 的同仁多年来为使其可用所做的努力,尽管它在更广泛的软件社区中普及缓慢。
如果没有 `perf` 对 Intel PT 的广泛支持,magic-trace 就不可能存在。`perf` 承担了大部分解读 Intel PT 输出数据的工作,若没有他们的努力,magic-trace 很可能根本不会问世。感谢你们,`perf` 开发者。
[magic-trace.org](https://magic-trace.org) 是 [Perfetto](https://github.com/janestreet/magic-trace/wiki/About-the-UI), 的 fork,仅做了少量修改。我们要感谢 Google 负责该项目的同仁。这是一个高质量的代码库,很好地解决了一个难题。
magic-trace 背后的思想绝非独创。我们整理了一份 [先前工作](https://github.com/janestreet/magic-trace/wiki/Prior-art) 列表,记录了影响其设计的内容。