Page 35 - 《软件学报》2025年第7期
P. 35

2956                                                       软件学报  2025  年第  36  卷第  7  期


                    (2) SemaAFL  在编译器代码覆盖率方面与其他测试工具的横向对比.
                    (3) SemaAFL  在探测现代编译器中的缺陷方面表现如何.
                    综上所述, 本节的实验评估将从可靠性和可用性、代码覆盖率和实际找缺陷的能力                             3  个层面, 全方位地考察
                 SemaAFL  的优势和局限性, 为后续工作的改进提供重要参考.

                 4.1   实验设置
                    为了回答第     1  个问题, 我们整理了一个包含       1 800  个测试程序的测试集, 涵盖了       C  语言的各类特性. 在这个集
                 合上运行   SemaAFL、AFL++和    GrayC  这  3  个工具共计  5  遍, 每遍持续  24 h, 合计  15  个  CPU  日. 运行过程中会实
                 时记录工具发生的崩溃和无效变异的数量及比例, 通过这些指标可以比较全面地评估                             3  个工具的可靠性和可用
                 性. 崩溃频率反映了工具的可靠性, 频繁崩溃说明工具本身可能存在缺陷且对测试用例的处理能力有限. 而无效变
                 异程序的比例则反映了工具对具备不同特性的程序的适应性, 比例越低说明工具的通用性越好. 通过横向对比                                    3
                 个工具在这两项指标上的表现, 可以比较客观地评判                 SemaAFL  的可靠性和可用性水平.
                    为了回答第     2  个问题, 我们用同样的     1 800  个  C  程序作为种子程序池, 对两个目前最广为使用的            C/C++编译
                 器  GCC  和  Clang  进行模糊测试. 我们会在   GCC  和  Clang  最新的已发布版本上     (也就是  GCC-14  和  Clang-18) 测
                 量  SemaAFL、AFL++和  GrayC  对编译器的实时分支覆盖率. 对所有的            3  个测试工具, 我们会在两个编译器上运
                 行  5  遍, 每遍持续  24 h, 全部共计消耗  30  个  CPU  日.
                    为了回答第     3  个问题, 我们选择两个目前最广为使用的           C/C++编译器   GCC  和  Clang  作为测试对象, 并在它们
                 最新发布的稳定版本       (即  GCC-14  和  Clang-18) 上运行  SemaAFL  进行为期一周的模糊测试. 在测试结束后, 我们会
                 汇总  SemaAFL  报告的崩溃信息, 并人工分析缺陷成因并进行去重. 对于确认的触发编译器缺陷的测试用例, 我们
                 会整理成符合     GCC  和  Clang  社区规范的缺陷报告, 提交给相应的开发者进行确认和修复.
                    上述所有实验都在运行         Ubuntu 22.04  的  DELL PowerEdge R6515  服务器上进行. 该服务器配备了一个     64  核
                 (128  线程) 的  AMD EPYC 7713P  处理器和  128 GiB  内存.

                 4.2   可用性和可靠性对比

                 4.2.1    可用性对比
                    如表  3  所示, SemaAFL  在  5  次  24 h  的实验中, 平均进行了超过  370  万次变异, 这一速度远超过同为基于语义
                 信息的变异工具      GrayC, 并相当接近   AFL++. 这是因为    AFL++的所有变异均在字符级别进行, 无需进行复杂的分
                 词和语法语义解析, 从而节省了大量时间. 在无效输出的对比上, SemaAFL                   平均有   220  万次变异未能产生有效输
                 出, 约占总变异次数的       58%. 这一比例在很大程度上反映了语义级别变异操作符苛刻的调用条件. 尽管                        SemaAFL
                 的无效变异比例平均达到         58%, 但相比于同为语义级别变异工具的            GrayC  的  83%, SemaAFL  仍领先了接近  25%.
                 这得益于我们设计的操作符高效选择算法. 同时从表                 3  可以看出, SemaAFL  无效输出的主要来源是操作符无输出,
                 占比为   92.4%. 而  GrayC  最大的来源却是输出与输入相同, 占比为         89.9%, 这是因为我们的实现在变异失败时不会
                 有任何输出, 而    GrayC  在变异失败时会将输入原封不动输出. 对于             AFL++而言, 由于字符级别的变异天然就较难
                 失败  (包括无输出、输出与输入相同等), 在我们所有的              5  次  24 h  实验中, 我们未曾观测到   AFL++的无效变异.


                                                   表 3 无效变异频率对比

                    工具      总变异次数      无输出      输出和输入相同       输出和历史输出相同        总无效变异次数        无效比例 (%)
                  SemaAFL    3 763 299  2 041 018  102 031         65 514         2 208 563     58.68
                   AFL++     4 512 455   0           0               0               0            0
                   GrayC     716 227     0         539 986         60 589         600 575       83.85

                    在变异生成的可编译程序数量上, 如表             4  所示, 在  24 h  的测试周期内, SemaAFL  远超  AFL++ (领先  12  倍) 和
                 GrayC (领先  88%), 这很大一部分是得益于与灰盒模糊测试工具的结合. 在变异生成的可编译程序比例上,
                 SemaAFL  以高达  77%  的比例遥遥领先     AFL++, 且相当接近    GrayC. 这是因为  GrayC  仅设计实现了    5  个语义级别
   30   31   32   33   34   35   36   37   38   39   40