告别隐藏Bug:erlang.mk集成Dialyzer、Xref与Concuerror静态分析实战指南
告别隐藏Bugerlang.mk集成Dialyzer、Xref与Concuerror静态分析实战指南【免费下载链接】erlang.mkA build tool for Erlang that just works.项目地址: https://gitcode.com/gh_mirrors/er/erlang.mkerlang.mk是一款Erlang 构建工具开箱即用A build tool for Erlang that just works它不仅负责编译与测试还内置了三大静态分析能力Dialyzer 类型检查、Xref 交叉引用分析、Concuerror 并发错误检测。本文带你用最少配置把这三类平时看不见、上线才炸的 Bug 统统揪出来。为什么 Erlang 项目需要静态分析Erlang 以让错误暴露得早一点为哲学但仍有三类隐患难以靠测试全覆盖隐患类型典型表现检测工具类型不匹配、死代码1 2这类永远走不到的分支 Dialyzer调用未定义函数、无用导出重构后遗留的幽灵调用 Xref死锁、竞态条件只在特定调度下偶发几乎无法复现⚡ Concuerror三个工具在 erlang.mk 中都以 Make 目标的形式提供无需编写任何 Erlang 胶水代码这正是 erlang.mk just works 理念的体现。第 1 站Dialyzer——零误报的类型检查器官方文档见 doc/src/guide/dialyzer.asciidoc插件源码见 plugins/dialyzer.mkDialyzer 使用成功类型分析success typing技术保证不产生误报它报出的每一条警告都真实存在。它能检测类型错误、死代码等程序不一致之处。一键运行与 PLT 全自动管理Dialyzer 依赖一个 PLT 文件缓存了 OTP 与依赖库的分析信息。erlang.mk 已把这件事完全自动化见 plugins/dialyzer.mk 中$(DIALYZER_PLT): deps app规则PLT 缺失时自动生成默认存放在项目根的.$(PROJECT).pltErlang 版本变化导致 PLT 失效时自动重建make distclean时自动清理。因此你只需要一条命令make dialyze默认检查项与关键配置erlang.mk 默认启用了两个高价值警告见 plugins/dialyzer.mk 第 13 行DIALYZER_OPTS ? -Werror_handling -Wunmatched_returns-Werror_handling调用gen_tcp:connect/3等会失败的函数却忽略其返回值-Wunmatched_returns函数返回值与调用方期望不一致。常用配置变量速查变量作用默认值DIALYZER_PLTPLT 文件路径.$(PROJECT).pltPLT_APPS额外加入 PLT 的 OTP 应用空DIALYZER_DIRS分析范围默认分析源码--src -r srcDIALYZER_OPTS额外警告开关见上 提示默认分析的是源码若想分析编译产物例如使用了 parse_transform 的项目设置DIALYZER_DIRS -r ebin即可。让make check顺带做类型检查Dialyzer 目标已挂接到checkcheck:: dialyzer。也就是说你每次运行make check单元测试跑完后Dialyzer 会立刻跟进分析形成测试 静态分析双保险。第 2 站Xref——跨模块依赖与幽灵调用分析官方文档见 doc/src/guide/xref.asciidoc插件源码见 plugins/xref.mkXref 用于分析函数、模块、应用之间的调用关系最擅长抓住调用了不存在的函数这类重构后遗留的 Bug。默认只查最致命的一项默认检查项非常克制见 plugins/xref.mk 第 16 行XREF_CHECKS ? [undefined_function_calls]即只报告调用了未定义函数——这是最容易在生产环境引发undef崩溃的问题。发现警告时erlang.mk 会让make直接报错退出方便接入 CI。按需开启更多检查项检查项通过命令行变量即可切换无需改代码make xref XREF_CHECKSexports_not_used make xref XREF_CHECKS[undefined_function_calls, exports_not_used]支持的预定义检查包括undefined_function_calls、undefined_functions、exports_not_used、deprecated_function_calls、deprecated_functions等。信息型分析谁在依赖我Xref 还支持只查询、不报错的信息型分析非常适合架构审查# 查看哪些模块依赖 cowboy_req make xref XREF_CHECKS{module_use, cowboy_req} # 用 Xref DSL 查询所有外部调用 make xref qXC信息型分析call/use/module_call/module_use/application_call/application_use的输出只是列表不会导致构建失败。分析范围与白名单机制默认只分析当前项目。多应用仓库或需要查依赖时可扩大范围make xref XREF_SCOPEapp apps deps otp对于预期内的警告比如需兼容多个 OTP 版本erlang.mk 提供 Rebar 兼容的行内忽略-ignore_xref({log, 1}). %% 忽略本模块 log/1 -ignore_xref(my_mod). %% 忽略整个模块也可用XREF_IGNORE变量做全项目级忽略。行为回调如gen_server的init/1在exports_not_used检查中会被自动豁免避免误报刷屏。第 3 站Concuerror——并发 Bug 的照妖镜官方文档见 doc/src/guide/concuerror.asciidoc插件源码见 plugins/concuerror.mk死锁、竞态条件的可怕之处在于只在极少数特定调度下出现随机重跑一万次也未必复现。Concuerror 是 Erlang 的无状态模型检测model checking工具它系统地遍历调度组合因而不仅能抓 Bug还能验证该类 Bug 确实不存在——这是随机化测试做不到的。三步接入 Concuerror第 1 步写测试用例一个导出的 0 元函数即可例如-export([start_stop/0]). start_stop() - SupPid start_listener(), ok do_something(), stop(SupPid).第 2 步在 Makefile 中声明测试清单CONCUERROR_TESTS my_concuerror:start_stop my_concuerror:info第 3 步运行make concuerror日志与 HTML 报告由于错误路径输出可能非常庞大Concuerror 的屏幕只显示进度完整错误写入日志文件默认logs/目录可用CONCUERROR_LOGS_DIR修改。erlang.mk 会自动生成索引页logs/concuerror.html点进去即可逐个查看每个用例的报告见 plugins/concuerror.mk 中concuerror_html_report模板。补充配置CONCUERROR_OPTS可传全局选项如-k也可在模块内用-concuerror_options([]).属性按模块配置。与另外两位搭档一致make check同样会自动触发 Concuerror 分析。三把利器怎么选一张表说清DialyzerXrefConcuerror命令make dialyzemake xrefmake concuerror抓什么类型错误、死代码、错误处理缺失未定义调用、无用导出、依赖关系死锁、竞态等并发错误误报率零误报可精确白名单忽略系统性验证非随机首次开销建 PLT 较慢之后秒级极低较高模型检测接入 CImake check自动包含make check不强制建议加入make check自动包含推荐的日常节奏 ️每次提交make check—— 测试、Dialyzer含 Concuerror若已配置一把梭重构后make xref XREF_CHECKS[undefined_function_calls, exports_not_used]清场发布前对核心并发模块跑一轮make concuerror拿到无并发错误的确定性结论。小结erlang.mk 把 Erlang 生态最强的三个静态分析工具收敛成三条 Make 命令Dialyzer 管类型、Xref 管依赖、Concuerror 管并发并且全部与make check深度集成、零误报策略、自动化 PLT 管理。对新手而言只需在 Makefile 中include erlang.mk即可获得一套生产级的Bug 拦截网。核心参考文件plugins/dialyzer.mk —— Dialyzer 插件实现plugins/xref.mk —— Xref 插件实现plugins/concuerror.mk —— Concuerror 插件实现test/plugin_dialyzer.mk、test/plugin_xref.mk —— 各插件的行为测试用例是理解配置项的活教材【免费下载链接】erlang.mkA build tool for Erlang that just works.项目地址: https://gitcode.com/gh_mirrors/er/erlang.mk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考