用调用图分析器把会 panic 的函数一个个揪出来
来源:tweedegolf.nl — 2026-10-27
📋 概述
Tweede golf 与微软在 Open Device Partnership 下发布了 Call Graph Analyzer(CGA),思路是从单态化后的 MIR 里抽出调用图,再顺着图找出编译进二进制的函数里哪些可能 panic。cargo cga check 能直接指着源码说"这一行调用的 strict_sub 可能 panic"。文章先辨析了为什么值得消除 panic:嵌入式场景下 panic 带来大量字符串与格式化代码,可用 defmt 或 -Cpanic=immediate-abort 压缩;关键路径(对外服务、固件升级与 bootloader)不能因为坏输入崩掉;panic 处理代码自身也不该 panic。但作者明确说追求零 panic 既难又愚蠢——Result 只是把负担推上调用栈,最后还是在根部 abort;真正有价值的是让 panic 路径显式化并做回归分析。与既有方案比:链接器法只能判断整个二进制里有没有 panic;ELF 调试信息法受内联影响;HIR 分析看不到依赖里的代码与编译器插入的边界检查;rust-analyzer 那条独立管线快,但常啃不动复杂 proc macro。MIR 法能看见依赖与 std 的代码,代价是此时 LLVM 还没清掉不可达分支,会有误报。
🔑 核心要点
- 产品形态很直接:cargo cga check 会指出具体哪一行调用了可能 panic 的方法,例如 strict_sub
- 消除 panic 的真正理由有三类:嵌入式代码体积、对外服务与固件升级等关键路径、以及 panic 处理代码自身不允许再 panic
- 作者对"零 panic"态度明确:把 Result 一路往上传只是把负担推上调用栈,最后仍在根部 abort,与直接 panic 无异
- 既有方案各有盲区:链接器法只判定整个二进制有无 panic,ELF 法受内联影响,HIR 法看不到依赖与编译器插入的断言
- 选 MIR 是为了完整:能看到依赖与标准库里的全部代码,代价是 LLVM 尚未清除不可达分支,会有误报
- 真正的价值是可视化与回归:让 panic 路径显式、可讨论,并在新 panic 路径出现时被工具提醒
💡 金句
努力做到零 panic 非常困难,而且相当愚蠢:代码极少没有假设。到处返回 Result 只是把负担顺着调用栈往上推,直到你最终还是在根部中止——那和直接 panic 的行为本质上一样。
👍 0
👎 0
← 返回 Lobsters 首页