name: phx:trace description: 构建递归调用树以追踪函数如何从入口点被调用。用于调试“这个值从哪里来?”或规划签名更改。
调用追踪
构建调用树,显示函数如何从入口点被调用。
铁律 - 永不违反
- 首先使用
mix xref callers- 它是权威的;grep 仅作为备用 - 在入口点停止 - 控制器、LiveView 回调、Oban 工作者、GenServer 回调
- 追踪访问过的 MFAs - 防止循环调用导致的无限循环
- 提取参数模式 - 仅知道“谁调用”不够;他们如何调用很重要
- 最大深度 10 - 更深的树表示架构问题,不是有用的追踪
何时构建调用树(主动使用)
| 条件 | 为什么调用树有帮助 |
|---|---|
| 运行时出现意外的 nil/值 | 追踪值的来源 |
| 无法在本地重现错误 | 查看所有到达代码的入口点 |
| 更改函数签名 | 找到所有调用者及其参数模式 |
| 不完整的堆栈跟踪 | 获取完整路径上下文 |
| “X 从哪里来?” | 数据流问题的视觉答案 |
快速追踪
# 查找所有调用者
mix xref callers MyApp.Accounts.update_user/2
# 输出: lib/web/controllers/user_controller.ex:45: MyApp.Accounts.update_user/2
# 读取该位置以查看参数
入口点(在此停止)
| 模式 | 类型 |
|---|---|
def mount/3, def handle_event/3 |
LiveView |
def index/2, def show/2, def create/2 |
Controller |
def perform(%Oban.Job{}) |
Oban Worker |
def handle_call/3, def handle_cast/2 |
GenServer |
委托给调用追踪代理
对于具有参数提取和并行类别追踪的完整递归树:
Task(subagent_type: "call-tracer", prompt: "为 MyApp.Accounts.update_user/2 构建调用树")
调用追踪代理使用并行子代理为每个入口点类别:
- 控制器子代理(HTTP 路径)
- LiveView 子代理(WebSocket 路径)
- 工作者子代理(后台作业)
- 内部子代理(跨上下文调用)
每个都获得新鲜的 200k 上下文用于深度探索。
输出位置
.claude/plans/{slug}/research/call-tree-{function}.md
参考
对于详细模式:
references/mix-xref-usage.md- 完整的 mix xref 命令和选项references/entry-points.md- 所有 Phoenix/OTP 入口点模式references/argument-extraction.md- AST 解析参数模式