ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Infer `debug` 子命令完全指南:透视内部数据结构、过程摘要与调用图

Infer `debug` 子命令完全指南:透视内部数据结构、过程摘要与调用图 静态分析代码质量开发工具【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址https://gitcode.com/gh_mirrors/infer/infer点击查看免费下载导读infer debug是 Infer 静态分析器中面向分析与调试场景的命令行工具用于打印 Infer 捕获与分析过程中的内部数据结构——包括全局类型环境global type environment、每个被捕获的过程procedure即函数或方法的属性、摘要summary与静态调用图以及捕获到的源文件清单及其类型环境。本文以inferv1.1.0 的 man 手册原文为骨架结合仓库中infer debug的 OCaml 实现源码InferCommandImplementation.ml与选项定义Config.ml逐项讲解每个开关的作用、输出位置与典型使用场景。读完本文你将能够熟练使用infer debug查看捕获结果、导出 JSON 摘要、输出 DOT 格式的调用图/CFG并借助--procedures-filter、--select等参数高效定位特定过程或源文件。命令概览与基本用法infer debug的核心职责是打印 Infer 内部数据结构它不执行分析而是读取已有捕获capture与分析产物。其基本语法如下来自 infer-debug.txtinfer debug --global-tenv infer debug --procedures [options] infer debug --source-files [options]三个模式分别对应--global-tenv打印全局类型环境如果存在--procedures打印 Infer 捕获到的每个过程函数/方法的相关信息--source-files打印被捕获源文件的相关信息。必须且至少传入上述三个开关之一否则命令会直接报错退出。这一约束在源码中有明确体现infer/src/integration/InferCommandImplementation.ml中的debug ()函数开头即检查if not Config.(global_tenv || procedures || source_files || Option.is_some export_textual) then L.die UserError Expected at least one of --global-tenv, --procedures, --source-files or \ --export-textual.\n即infer debug要求至少传入--global-tenv、--procedures、--source-files或--export-textual之一否则抛出UserError。注意这里的--export-textual也属于可用入口详见下文导出 textual SIL小节。通用选项以下选项对所有模式均可用选项说明--help显示本手册帮助信息--help-format { auto \| groff \| pager \| plain }以指定格式显示帮助。auto模式在环境变量TERM为dumb或未定义时使用plain格式否则使用pager格式--help-full显示包含全部内部选项INTERNAL OPTIONS 一节的完整手册--preanalysis-html是否启用预处理阶段preanalysis的 HTML 节点打印默认关闭false以便专注于已启用分析的调试输出反向开关为--no-preanalysis-html--select (N\|all)选择编号为 N 的选项或全部选项。省略该参数时会以交互方式提示输入详见下文交互式选择这些选项定义于 Config.ml并通过CLOpt.mk_bool等构造器注册每个布尔开关都有对应的--no-name反向形式。调试全局类型环境DEBUG GLOBAL TYPE ENVIRONMENT--global-tenv激活后打印全局类型环境global type environment。反向开关--no-global-tenv。全局类型环境是 Infer 在捕获阶段构建的、描述程序中所有可见类型类、结构体、类型别名等的全局映射。在源码实现中InferCommandImplementation.ml 第 17-22 行当Config.global_tenv为真时match Tenv.Global.load () with | None - L.result No global type environment was found.. | Some tenv - L.result Global type environment:\n[v%a] Tenv.pp tenv即从磁盘加载全局类型环境若不存在则输出No global type environment was found.否则以Tenv.pp的可读文本形式打印整个类型环境。该数据由Tenv.Global模块管理通常在分析前由前端如 Clang 前端写入结果目录。调试过程DEBUG PROCEDURES--procedures模式是infer debug最常用的入口它围绕过程procedure即函数/方法提供多种信息视图。相关开关定义在 Config.ml 中并归类到manual_debug_procedures DEBUG PROCEDURES帮助分组。基础信息开关选项默认值说明--procedures关打印 Infer 发现的函数与方法过程的名称等基础信息--procedures-name关在--procedures的输出中包含过程名称--procedures-attributes关在--procedures的输出中打印每个过程的属性attributes如参数、返回类型、访问权限等--procedures-callees关在--procedures的输出中打印每个过程的静态被调用者callees--procedures-source-file开在--procedures的输出中包含过程定义或声明所在的源文件反向开关--no-procedures-source-file--procedures-definedness开在--procedures的输出中显示过程的定义性即过程定义是否被找到、是否仅有声明或是否为自动生成的 Objective-C accessor反向开关--no-procedures-definedness以基础打印为例源码中通过Config.Procedures.pp_all一次性组合上述各开关的输出L.result %a Config.( Procedures.pp_all ~filter ~proc_name:procedures_name ~defined:procedures_definedness ~source_file:procedures_source_file ~proc_attributes:procedures_attributes ~proc_cfg:procedures_cfg ~callees:procedures_callees ) ()过滤--procedures-filter filter与--procedures配合使用时只打印匹配指定过滤器的过程。过滤器格式为path_pattern:procedure_name其中模式按OCaml Str 正则表达式解释。例如只保留名为foo的方法可以使用.*:foo或者简写为foo。过滤器的实现位于 InferCommandImplementation.ml第 24 行通过Lazy.force Filtering.procedures_filter惰性求值得到并贯穿整个--procedures分支无论是打印摘要、导出 JSON 还是生成调用图filter都会被传入Procedures.get_all ~filter。摘要导出文本与 JSON选项说明--procedures-summary打印每个过程的摘要summary。摘要记录了分析器对每个过程的分析结论如内存泄漏、空指针等抽象状态。反向开关--no-procedures-summary--procedures-summary-json将每个过程的摘要以 JSON 形式输出。反向开关--no-procedures-summary-json--procedures-summary-skip-empty完全跳过没有摘要的过程。在分析大型项目的一小部分时非常有用常与--procedures-summary或--procedures-summary-json配合使用也常与--changed-files-index联用。反向开关--no-procedures-summary-skip-empty--dump-json-summaries直接将每个已分析过程的 JSON 摘要导出到output-dir/all_summaries.json即results-dir/all_summaries.json。反向开关--no-dump-json-summaries--dump-json-specialized-call-graph直接将特化调用图specialized call graph的 JSON 导出到output-dir/specialized_call_graph.json。反向开关--no-dump-json-specialized-call-graph在实现层面InferCommandImplementation.ml 第 32-84 行当--procedures-summary或--procedures-summary-json被激活时逻辑按以下优先级展开若--dump-json-summaries开启则通过Summary.OnDisk.get读取每个过程的摘要以Summary.yojson_of_t序列化为 JSON 列表写入Config.results_dir下的all_summaries.json否则若--dump-json-specialized-call-graph开启则基于每个过程摘要的pulsepayload通过PulseSpecializedCallGraph.JsonBuilder构建特化调用图写入specialized_call_graph.json输出前会按Procname.compare排序以保证确定性否则进入交互选择流程见下文再按--procedures-summary-json决定输出 JSON 到 stdout 还是以Summary.pp_text打印可读文本。--procedures-summary-skip-empty在源码中体现为过滤器组合第 26-31 行let filter source_file proc_name procedures_filter source_file proc_name if Config.procedures_summary_skip_empty then Option.is_some (summary_of proc_name) else true即启用后没有摘要的过程会被直接过滤掉。调用图与 CFG 的 DOT 输出选项输出文件说明--procedures-call-graphinfer-out/captured/syntactic-call-graph.dot输出语法调用图syntactic call graph的 dotty 文件。该图从所有被捕获过程出发或由--changed-files-index决定的过程集合可达。反向开关--no-procedures-call-graph--procedures-cfginfer-out/captured/file_name/proc_name.dot为--procedures输出中的每个过程输出控制流图CFG的 dotty 文件。反向开关--no-procedures-cfg在实现中InferCommandImplementation.ml 第 85-93 行--procedures-call-graph优先读取配置文件SourceFile.read_config_files_to_analyze确定的文件集合否则使用全部源文件然后通过SyntacticCallGraph.build_from_sources构建并以to_dotty写出。而--procedures-cfg的实现与--source-files-cfg共享一套逻辑第 127-140 行遍历源文件、为每个过程中的每个过程加载Procdesc过程描述即 CFG最后调用DotCfg.emit_frontend_cfg生成 DOT 文件并打印提示CFGs written in %s/*/%s。交互式选择--select (N|all)当同时开启了摘要输出但未指定--dump-json-*时infer debug --procedures会进入交互选择流程。--select用于指定选择编号为 N 的选项或all若省略则在终端中交互提示输入。该逻辑实现在 Procedures.ml 的select_proc_names_interactive中若没有匹配的过程直接打印No procedures found若--select N中 N 超出过程总数抛出UserErrorCannot select result #%d out of only %d procedures若仅有一个匹配过程自动选中它并打印Selected proc name: ...若--select all选中全部若--select N只选中第 N 个若省略--select则列出全部过程的编号0: proc_name格式提示输入一个编号、a全部或q退出。调试源文件DEBUG SOURCE FILES--source-files模式围绕被捕获的源文件提供信息相关开关归类于manual_debug_source_files DEBUG SOURCE FILES。基础信息开关选项默认值说明--source-files关打印 Infer 发现的源文件--source-files-freshly-captured关在--source-files输出中打印该源文件是否在最近一次捕获阶段中被捕获freshly captured--source-files-procedure-names关在--source-files输出中打印每个源文件包含的过程名称--source-files-type-environment关在--source-files输出中打印每个源文件的类型环境--source-files-filter filter—与--source-files配合时只打印匹配的源文件。过滤器是应匹配文件路径的模式按 OCaml Str 正则表达式解释基础输出的实现位于 InferCommandImplementation.ml 第 121-126 行通过SourceFiles.pp_all结合~type_environment、~procedure_names、~freshly_captured三个开关打印过滤器来自Lazy.force Filtering.source_files_filter。文件级调用图与分区选项输出/行为说明--source-files-call-graphinfer-out/captured/file-call-graph.dot输出基于文件的语法调用图所有被捕获过程含已知编译单元按文件聚合的调用关系图。反向开关--no-source-files-call-graph--source-files-call-graph-partition intinfer-out/captured/workerXX.idx利用静态调用图信息将被捕获源文件集合划分为指定数量的分区partition生成的文件列表位于infer-out/captured/workerXX.idx。不设置该选项则跳过分区。该功能用于分布式分析--source-files-cfginfer-out/captured/...为--source-files输出中的每个源文件输出控制流图dotty 文件。反向开关--no-source-files-cfg实现上第 101-105 行三个开关互斥分支--source-files-call-graph直接调用SourceFileGraph.to_dotty file-call-graph.dot--source-files-call-graph-partition则调用SourceFileGraph.partition_source_file_call_graph ~n_workers做分区。捕获数据库操作提取与补全以下两个开关用于操作捕获数据库capture database是增量/分布式分析流程中的关键工具--extract-capture-from path提供包含捕获数据库的 Infer results 目录路径。配合必须使用的--changed-files-index提供文件列表在--results-dir指定的位置创建一个只包含这些文件相关产物的新捕获数据库。源码第 106-113 行中若未提供--changed-files-index会抛出UserErrorWhen extracting a capture database, --changed-files-index must be specified.随后调用CaptureManipulation.extract。--complete-capture-from path提供包含捕获数据库的 Infer results 目录路径。根据结果目录中的missing-*文件将--results-dir指定的捕获数据库从输入数据库补全complete。命令的退出码等于添加到捕获数据库中的行数。实现位于第 114-119 行通过CaptureManipulation.complete完成并输出MODIFIED或UNMODIFIED。导出 textual SIL--export-textual string将捕获数据库capture.db中的 textual SIL 导出到指定输出目录每个源文件对应一个.sil文件同时生成manifest.json将源文件路径映射到其.sil文件名前提条件需要先前使用--dump-textual或--store-textual进行过捕获。源码实现第 142-160 行起中导出时会先IUnix.mkdir_p创建输出目录按SourceFile.compare对源文件排序以保证输出顺序确定并使用used_names表处理文件名冲突例如src/foo.c与lib/foo.c的 basename 都是foo后者会被命名为foo_1.sil。manifest.json会记录每个源文件相对项目根目录到其.sil文件名及过程名称列表的映射。该功能在debug ()的入口校验中被视为可独立使用的模式之一见上文源码第 12 行。运行环境与配置文件环境变量infer debug遵循infer(1)手册中定义的环境变量约定变量说明INFER_ARGS向所有 Infer 命令注入额外的命令行参数INFERCONFIG指定额外的配置文件路径INFER_STRICT_MODE启用严格模式strict mode开启更严格的参数与使用检查配置文件infer debug同样支持.inferconfig配置文件位于项目根目录其规则与infer(1)的 FILES 一节一致命令行参数优先级高于配置文件。因此常用调试参数如--procedures-filter、--results-dir也可以写入.inferconfig统一管理。典型使用场景速查查看某个文件里所有过程及其摘要infer debug --procedures --procedures-filter path/to/file.c:.* --procedures-summary导出全部过程的 JSON 摘要供二次分析infer debug --procedures --dump-json-summaries # 结果写入 results-dir/all_summaries.json输出语法调用图与每个过程的 CFGinfer debug --procedures --procedures-call-graph --procedures-cfg # infer-out/captured/syntactic-call-graph.dot # infer-out/captured/file_name/proc_name.dot为分布式分析切分源文件infer debug --source-files --source-files-call-graph-partition 8 # 生成 infer-out/captured/worker00.idx ... worker07.idx从已有捕获库中提取子集或补全捕获库infer debug --source-files --extract-capture-from /path/to/old-results \ --changed-files-index changed-files.txt --results-dir infer-out-new infer debug --source-files --complete-capture-from /path/to/old-results导出 textual SIL 供外部消费infer capture --dump-textual . # 捕获时同时存储 textual SIL infer debug --export-textual /tmp/textual-sil相关命令infer debug的输出摘要、调用图、类型环境与以下命令/文档互补infer exploreinfer-explore.txt在交互界面中浏览分析结果与错误轨迹infer reportinfer-report.txt以文本/JSON/CSV 等格式输出分析报告。三者配合使用可以覆盖调试数据结构 → 探索分析结果 → 生成正式报告的完整分析工作流。小结infer debug是深入 Infer 内部机制的第一入口它把捕获阶段产生的类型环境、过程属性、分析摘要、调用图、CFG 乃至 textual SIL 全部以可读或机器可解析JSON/DOT的形式暴露出来。其全部选项与行为均可在 infer/man/man1/infer-debug.txt对应帮助页面 man-infer-debug.md中查阅实现细节位于 InferCommandImplementation.ml 的debug ()函数选项定义位于 Config.ml。建议读者结合自己的捕获产物实际运行以上命令组合以直观理解 Infer 的数据流。赞分享静态分析代码质量开发工具【免费下载链接】inferA static analyzer for Java, C, C, and Objective-C项目地址https://gitcode.com/gh_mirrors/infer/infer点击查看免费下载相关推荐Infer Debug 命令完全指南深入探查 infer 内部数据结构Infer Debug 命令完全指南深入探查 infer 内部数据结构 本篇指南围绕静态分析器 Infer 的 infer debug 子命令展开讲解如何借静态分析代码质量开发工具Infer Debug 命令完全指南深入剖析 infer 内部数据结构与捕获产物Infer Debug 命令完全指南深入剖析 infer 内部数据结构与捕获产物 导读 infer debug 是 Facebook Infer 静态分析器静态分析代码质量开发工具SumatraPDF 命令行工具指南用 sumatrapdf-tool info 透视 PDF 内部资源结构SumatraPDF 命令行工具指南用 sumatrapdf tool info 透视 PDF 内部资源结构 本文基于 SumatraPDF 官方文档 Too桌面应用文档创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进