系统性沿调用链逆向排查缺陷,快速定位问题的最初触发点
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "Root Cause Tracing" 技能: 1. 下载 https://raw.githubusercontent.com/obra/clank/main/skills/debugging/root-cause-tracing/SKILL.md 2. 保存为 ~/.claude/skills/root-cause-tracing/SKILL.md 3. 装好后重载技能,告诉我可以用了
请根据这段报错堆栈和关键代码,按调用链逆向追踪空指针异常的真正触发点,标出每一层函数的输入、输出和可疑变量,并给出最可能的根因与修复建议。
一份按调用层级展开的根因分析,指出异常最早出现的位置及修复思路。
下面是异步任务失败日志、任务调度流程和相关服务调用信息。请从报错点开始向上回溯,找出是哪个上游参数、状态变化或重试逻辑最先导致任务失败,并整理成排查报告。
一份说明任务失败传播路径的报告,明确最初触发原因和影响链路。
我有一个线上回归问题:新版本发布后某功能返回错误结果。请结合提交记录、调用栈和测试现象,逆向追踪根因,判断是哪个变更最可能引入了问题,并给出验证步骤。
一份回归缺陷分析,包含可疑变更、根因判断和验证方案。
Bugs often manifest deep in the call stack (git init in wrong directory, file created in wrong location, database opened with wrong path). Your instinct is to fix where the error appears, but that's treating a symptom.
Core principle: Trace backward through the call chain until you find the original trigger, then fix at the source.
digraph when_to_use {
"Bug appears deep in stack?" [shape=diamond];
"Can trace backwards?" [shape=diamond];
"Fix at symptom point" [shape=box];
"Trace to original trigger" [shape=box];
"BETTER: Also add defense-in-depth" [shape=box];
"Bug appears deep in stack?" -> "Can trace backwards?" [label="yes"];
"Can trace backwards?" -> "Trace to original trigger" [label="yes"];
"Can trace backwards?" -> "Fix at symptom point" [label="no - dead end"];
"Trace to original trigger" -> "BETTER: Also add defense-in-depth";
}
Use when:
Error: git init failed in /Users/jesse/project/packages/core
What code directly causes this?
await execFileAsync('git', ['init'], { cwd: projectDir });
WorktreeManager.createSessionWorktree(projectDir, sessionId)
→ called by Session.initializeWorkspace()
→ called by Session.create()
→ called by test at Project.create()
What value was passed?
projectDir = '' (empty string!)cwd resolves to process.cwd()Where did empty string come from?
const context = setupCoreTest(); // Returns { tempDir: '' }
Project.create('name', context.tempDir); // Accessed before beforeEach!
When you can't trace manually, add instrumentation:
// Before the problematic operation
async function gitInit(directory: string) {
const stack = new Error().stack;
console.error('DEBUG git init:', {
directory,
cwd: process.cwd(),
nodeEnv: process.env.NODE_ENV,
stack,
});
await execFileAsync('git', ['init'], { cwd: directory });
}
Critical: Use console.error() in tests (not logger - may not show)
Run and capture:
npm test 2>&1 | grep 'DEBUG git init'
Analyze stack traces:
If something appears during tests but you don't know which test:
Use the bisection script: @find-polluter.sh
./find-polluter.sh '.git' 'src/**/*.test.ts'
Runs tests one-by-one, stops at first polluter. See script for usage.
Symptom: .git created in packages/core/ (source code)
Trace chain:
git init runs in process.cwd() ← empty cwd parametercontext.tempDir before beforeEach{ tempDir: '' } initiallyRoot cause: Top-level variable initialization accessing empty value
Fix: Made tempDir a getter that throws if accessed before beforeEach
Also added defense-in-depth:
digraph principle {
"Found immediate cause" [shape=ellipse];
"Can trace one level up?" [shape=diamond];
"Trace backwards" [shape=box];
"Is this the source?" [shape=diamond];
…
帮助你为变量选择清晰准确、易维护的命名,提升代码可读性。
用四阶段系统化调试方法先定位根因,再制定可靠修复方案。