关于 gitnexus-pdg-query
gitnexus-pdg-query 是查询 GitNexus 程序依赖图并解读结果的技能,面向开发 `pdg_query` 工具或排查控制条件与变量流向的开发者。
主要功能
- 01查询控制依赖
- 02追踪定义到使用的数据流
- 03查找提前返回守卫
- 04解读 PDG 查询结果
- 05诊断缺失的 PDG 层
适用场景
- 01检查语句受什么条件控制
- 02追踪函数内的变量流向
- 03审查或扩展 `pdg_query`
- 04排查空查询结果
MCP 相关
该技能介绍 GitNexus 的 `pdg_query` MCP 工具及其 `controls` 和 `flows` 模式。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ abhigyanpatwari/ gitnexus --skill gitnexus-pdg-query安装后在 Claude Code 中输入/gitnexus-pdg-query确认已加载。
详细介绍
GitNexus 的 PDG 查询面
pdg_query MCP 工具及其读取的控制/数据依赖边的专家知识——即可选的 --pdg 程序依赖层。在改动 gitnexus/src/mcp/local/local-backend.ts(_pdgQueryImpl)或 pdg_query 工具定义之前,或需要解释 pdg_query 结果时,请先阅读本文。
何时使用
- “这条语句在什么条件下执行?”(守卫谓词)。
- “这个变量在函数内部流向哪里?”(def→use)。
- 守卫子句发现(提前返回守卫——涵盖了 #559 启发式)。
- 扩展或审查
pdg_query/ CDG / REACHING_DEF 读取路径。 - 调试空结果或异常结果的
pdg_query。
分层基底(构建顺序)
pdg_query 运行在污点分析所运行的同一个图之上。每一层都在 --pdg 之后可选启用;默认的 analyze 运行不记录其中任何一层(字节级一致)。
L1 CFG per-function basic blocks + control-flow edges (M1 #2081)
L2 REACHING_DEF GEN/KILL def→use data dependence (pure solver) (M2 #2082)
L5 CDG Ferrante control dependence (post-dominators) (M5 #2085)
这三者都是单个 CodeRelation 表中的 BasicBlock → BasicBlock 边(以 type 属性为键)。没有 Function → BasicBlock 边。
两种模式
pdg_query({ mode: 'controls', target })— CDG。对于锚定函数,每条边:控制谓词块 → 依赖块 +label中的分支方向('T'= 谓词的真/进入分支,'F'= 假/顺序执行分支)。进入提前返回/throw 块的边会被标记为guard: true。pdg_query({ mode: 'flows', target, variable? })— REACHING_DEF def→use 边;variable过滤到单个绑定。
target 是必需的——文件路径或符号/函数名(解析方式类似 context())。不存在无锚定模式(见下文)。
修正后的守卫子句 Cypher
RFC #567 §2 的形式([:CDG {label:'F'}])无法按原样运行。边是单个 CodeRelation 表 type 属性的值,而分支方向在 reason 中,不是 label 列:
MATCH (pred:BasicBlock)-[r:CodeRelation {type: 'CDG'}]->(dep:BasicBlock)
WHERE dep.text STARTS WITH 'return' OR dep.text STARTS WITH 'throw'
RETURN pred.startLine, r.reason AS branch, dep.startLine, dep.text
r.reason 是谓词到达提前退出时所采取的方向。对于 if (!ok) return;,return 走谓词的真分支('T'),受保护体走假分支('F')——极性取决于守卫,因此不要硬编码某一种方向。
注意事项(关键的几条)
- 始终锚定 + LIMIT 限定。 LadybugDB 没有关系属性索引,因此未锚定的
[:CDG*]/[:REACHING_DEF*]路径扫描是无界的。pdg_query要求target并对分页进行限定;原始cypher调用方必须自行锚定到文件 id 前缀或符号跨度。 - BasicBlock↔符号的关联是重建的。 没有
Function→BasicBlock边:块通过其 id 前缀(BasicBlock:<file>:<fnStartLine>:…)加上符号跨度内的startLine来匹配。BasicBlock 的startLine是基于 1 的,而符号节点的startLine/endLine是基于 0 的,因此两个边界都偏移+1([symStart+1, symEnd+1]):上界+1保留函数最后一行上的 guard/def/use,下界+1排除正上方一行的相邻函数的块。同一行/嵌套函数的锚定较粗糙。 - 没有 PDG 层 ⇒ 是提示,不是错误。 如果仓库未用
--pdg索引,工具返回{ results: [], note: "no PDG layer …" }(对RepoMeta.pdg.maxCdgEdgesPerFunction/maxReachingDefEdgesPerFunction的廉价元数据探测)。 - M5/M6 中 CDG 标签是二元的。 每个
switch-case 分支都是'T';每个 case 的条件尚未区分。 - 仅过程内。 跨函数流是污点分析的领域(
explain)。
镜像,不要分叉
_pdgQueryImpl 是 _explainImpl 的前半部分(WAL 包装、元数据无层探测、limit 校验、resolveSymbolCandidates 锚定),只是用 CDG/REACHING_DEF 替代了 TAINTED——并且没有污点分析的路径编解码 / 过程间 TAINT_PATH 机制。复用这些共享辅助函数;不要重新实现它们。