模糊测试 Gleam 编译器
你能通过生成随机程序来发现编译器中的错误吗?发布时间:2026年8月25日 星期二 介绍 我定期查看 Gleam 的变更日志和问题追踪器。我非常喜爱这个项目和为之贡献的人们。但每当我看到与代码生成或 Erlang 和 JavaScript 之间不同输出相关的问题时,我总是感到不安,因为没有办法“计算所有 Gleam 程序”,运行它们并查看是否有任何问题。我想象它就像一个棋盘,棋盘上有几乎无限数量的可能位置。但我们希望棋盘包含 Gleam 程序,并且希望有一个无限大的数据库,以查看这些程序是否能揭示未测试的边缘情况。 我第一次尝试做一些与此相关的事情实际上是提示一个大型语言模型(LLM)。我要求它阅读大量的过去 Gleam 问题,并通过“认真思考”来发现更多的边缘案例。它想出了各种位数组合、嵌套匿名函数、嵌套使用模式。可以预见,这种方法并没有产生太多结果。花了 20 美元的代币后,它发现了一个问题,这个问题被立即报告并修复: https://github.com/gleam-lang/gleam/issues/5613 。一个总比没有好。但“LLM 模糊测试”也有许多问题:成本高、不可预测,有点像拉动老虎机的杠杆。但我还有另一个想法我一直没有追求,因为老实说,这听起来只是很多工作:结构感知模糊测试。 结构感知模糊测试 编写软件是困难的,而人类在这方面并不出色。为了提供帮助,我们构建了其他可以部分自动化查找错误的软件。其中一个程序就是模糊测试器。它们生成随机化的输入,以供我们的程序处理。前提是,在大规模上,这些随机输入将以某种方式分布,从而显示出我们尚未考虑的边缘情况。模糊测试器可以从完全随机的打乱字节到高度结构化的语法感知抽象语法树(AST)。将完全随机的字节输入到程序中通常用于处理图像、文件、网络请求、协议等用例。确实有很多实例说明模糊测试发现了开源软件中的重大安全缺陷和错误。例如,zzuf 在 Firefox 中的发现,在图像文件中翻转某些位会导致浏览器崩溃: https://nvd.nist.gov/vuln/detail/CVE-2007-6715 。但模糊测试器还通过缓冲区溢出发现了真正可利用的安全缺陷。谷歌有一个名为“OSS Fuzz”的程序,持续对许多重要的开源项目进行模糊测试: https://google.github.io/oss-fuzz/ 在我们的案例中,我们不是在开发浏览器或网络协议。我们有一个编译器。这为结构感知模糊测试打开了可能性。这意味着我们不生成随机字节流,而是生成以源代码或 AST 形式的代码流。 关于 Gleam 的一些信息 Gleam 有一些特性使它成为一个特别有趣的模糊测试候选者。它为两个目标生成代码:JavaScript 和 Erlang。我们可以比较同一程序在两者目标上的输出,并标记任何差异。Gleam 的语法极简。至少与大多数其他流行编程语言相比。我们可以生成有效的程序,使用相对较少的代码涵盖语言提供的几乎所有概念。静态类型。无需多言,这是一项出色的功能,让我们确保程序在运行时不会崩溃。这并不意味着类型系统中就不会有任何错误。过去曾出现与类型推断相关的问题。但正如我们稍后将了解到的,每个语言的方面都将需要自己的测试方法。功能特性以及一切都是表达式使得组合和结构化程序非常方便。Rust。这可能容易被忽视,但 Gleam 编译器本身是用 Rust 编写的,这使得整合现有的模糊测试工具变得非常简单。我们可以测试编译器的部分,而无需运行任何 .gleam 文件。 我使用的资源 我们将深入探讨模糊测试器的更多技术方面。但我不会涉及很多代码或细节。如果你想了解更多,可以查看 Nick Fitzgerald 的这篇文章和博客。这篇文章是该项目的主要灵感来源:https://fitzgen.com/2020/08/24/writing-a-test-case-generator.html 我们的模糊测试器将基于生成,而不是基于变异。如果你想更好地理解这两者的区别,建议阅读这篇文章:https://fitzgen.com/2026/06/01/structure-aware-fuzzing-experiment.html 在这篇文章中,作者得出结论,至少对于 wasm,基于变异的方法发现了比基于生成的方法更多的问题。因此,未来可能值得在这个项目中实施这种方法!
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡