LLVM Regression 的设计

起因

某一天在和 ksyx 同学讨论参与 LLVM 开发过程中遇到的的事情,ksyx 同学提到 llvm 有一个开发者保存了每一天的 clang format 的构建产物,以便于出现问题时二分引入问题的 commit。由此我产生了一个想法,由于主要耗时是在构建庞大的 LLVM,我们何不像 mozregression 一样保存每个 commit 的构建产物,并提供一个工具来完成二分,于是就有了这个项目。

基本思路

基本思路很简单,就是一个使用预编译二进制版本的 git bisect。用户选定好和坏两个节点,然后程序自动找到二分的中间节点,用户判断好还是坏,如此迭代直至找到第一个坏的commit。

但是这个方案还不够优秀,于是提出了一些改进。

改进

检查

在这个二分的过程中,需要人工干预的部分是判断该 commit 是否正常。由于 llvm 作为一个编译基础设施项目,要判断的东西基本上是编译的输出和结果,不像 Firefox 那样需要进行复杂的 GUI 操作。因此可以考虑自动比对输出结果与正确和错误的结果。

更进一步的,我们可以设计两个机制:其一是维护两个集合,保存正确的和错误的结果,每当遇到不在集合里的结果,就询问用户,并且根据答案将结果加入集合,如此迭代,考虑到大部分情况下大多数结果应该是一样的,这样应该可以大大减少人工介入;其二是维护一个检测脚本模式,对于那些结果不稳定,但是具有特征的情况,用户可以提供一个脚本来判断正确和错误,这样可以大大减少人工判断,考虑到实际情况,这个脚本功能应当支持「无法判断」结果。

构建

可以将构建系统和 LLVM 项目的 CI 结合,复用 LLVM CI 的编译产物,减少资源占用。

分发

考虑到一台 CPU、内存储存和网络带宽俱佳的六边形服务器价格昂贵,又考虑到实际使用场景,应该类似 CDN 和镜像站,提供专门的储存分发节点,此类节点应具有良好的储存和网络环境,专职于内容分发,剩下的少数节点作为编译节点,编译节点应具有高性能的 CPU、充足的内存和快速的储存以加速构建。

为使这个网络简单易维护,考虑使用P2P技术,使得储存节点可以自动的互相获取编译产物,并且自动从编译节点获取编译产物。

编译节点类似于 Bit Torrent 中原始做种者的角色,编译并分发那些没有足够数量的存储节点的东西,当网络中有足够的节点保存有产物副本时,其删除产物以节省本机资源。编译节点同时分发一份映射表,类似于种子,其声明每个产物的校验和,以保证产物未被篡改。

检查节点

考虑到有些情况下,用户的空间和性能可能不足,我们可以设计一种节点,专职负责进行二分,通过用户计算机上简单低占用的程序通信。

这样可以带来以下的好处:由于检查节点可以和储存节点以及编译节点运行在同一内网,可以获得很高的带宽,甚至使用更直接的方式访问储存节点,这可以很好的提升性能和节省外部带宽;可以不受制于客户端的环境,比如 CPU 和内存资源不足,储存空间不足,带宽不足以及网络不稳定等。

更进一步,既然检查节点可以独立运行,则我们可以提供一个 Web 界面,以进一步降低对客户端的要求。

这项改进带来的问题是,我们需要设计一个权限机制和安全机制,以避免遭到攻击。


最后修改于 2022-10-13