Page 23 - 《软件学报》2026年第7期
P. 23

2708                                                       软件学报  2026  年第  37  卷第  7  期


                 版本的实现中包含更多的历史缺陷, 有助于使实验结果更具显著性. 最新版本的实现则是本实验进行时各个编译
                 器和虚拟机实现官方发布的最新版本. 最新版本一方面可以用于评估历史版本中检测到的缺陷是否被修复, 例如,
                 生成的测试程序在历史版本上触发了不一致, 但不一致在最新版本上消失, 则表明历史缺陷被修复; 另一方面, 可
                 以用于检测最新版本中是否存在未知的缺陷, 例如, 最新版本上依然存在的不一致有很大可能是现有测试工作中
                 尚未被发现的缺陷, 需要提交给开发人员做进一步的分析. 需要注意的是, ECJ 编译器并不会针对每个                              Java 版本
                 单独发布对应的编译器版本, 而是在一个发布版本中通过参数支持多个                        Java 语言版本的编译. 例如, 为了生成符
                 合  Java 8  规范的测试程序, 只需在编译时指定“-release 8”参数, 即可确保        ECJ 使用  Java 8  的编程语言规范对测试
                 程序进行编译. 因此, 在     ECJ 的最新版本中, 所有发布的        ECJ 版本均为   3.41.0. 对于历史版本, 本文分别选取了       ECJ
                 最早支持对应     Java 版本的发布版本, 以确保测试程序能够被正常地编译执行.
                  4.2.3    对比方法及评价指标
                    根据本文调研, 现有针对语言新特性的测试程序生成方法较少. 考虑到                       LumiX  在源代码级别生成测试程序,
                 本文选择同样在源码上生成测试程序的              JavaFuzzer 进行对比, 以评估   LumiX  的有效性. JavaFuzzer 是一个基于语
                                                        [5]
                 法的  Java 测试程序生成工具, 其设计了大量关于           Java 语法的生成规则, 包括循环结构、条件语句、函数调用以及
                 各种复杂的算术表达式等. 此外, 本文将           LumiX 与通用模糊测试工具        Fuzz4All  [21] 进行对比. Fuzz4All 是首个利用
                 大语言模型作为输入生成与变异引擎的通用模糊测试方法, 能够支持多语言及多特征测试, 已在                               Java 等语言上取
                 得一定成效, 可为新特性测试提供参考. 为了进一步评估 LumiX                中各个组成部分的有效性, 本文设计了             LumiX  的
                 变体方法   LumiJ. 具体说来, LumiJ 将  LumiX  中的历史揭错种子程序替换为         JavaFuzzer 随机生成的测试程序, 而保
                 持其他组成部分不变. 设计该变体的目的在于评估                 LumiX  中历史揭错种子程序以及大模型生成的新特性代码片
                 段的有效性. 为了进行公平的对比, 本实验进一步利用                JavaFuzzer 生成了  390  个 (与历史揭错种子程序数量相同)
                 随机测试程序作为       LumiJ 的种子程序, 累计包含     79 956  行代码、22 568  个变量定义和   1 987  个函数定义.
                    为了评估不同方法的有效性, 本实验设计了如下                3  个评价指标.
                    (1) 不一致缺陷数量
                    在本实验中, 不一致缺陷数量包括不同方法在编译和执行阶段的不一致行为数量. 在编译阶段, 不一致缺陷数
                 量表示两个    Java 编译器在同一个测试程序的编译结果不一致的数量. 在执行阶段, 不一致缺陷数量则表示两个
                 JVM  对同一个测试程序的执行结果不一致的数量. 通常来说, 编译结果的差异体现为编译错误信息的不一致, 因
                 此, 本实验使用编译错误信息作为不一致的标志对编译阶段的不一致缺陷进行去重. 而执行阶段的不一致则通常
                 体现为程序执行异常不一致或程序输出结果不一致. 为此, 本实验参考现有工作: 对于异常不一致, 根据程序执行
                 过程中触发的异常信息或崩溃信息进行去重; 对于输出结果不一致, 本实验利用                         Bug-inducing Commit 方法进行去
                 重. 最终, 去重后的编译阶段和执行阶段的不一致缺陷数量总和即为不一致缺陷数量评价指标.
                    (2) 代码覆盖率
                    本实验代码覆盖率包括不同方法在编译和执行阶段的代码覆盖率, 分别为编译器代码覆盖率和                                 JVM  代码覆
                 盖率. 具体来说, 本实验选择        OpenJDK 21  下的  javac  编译器和  HotSpot 虚拟机作为代表, 分别收集不同方法在
                 javac 编译器和  HotSpot 上的代码覆盖率. 为了收集       javac 编译器的代码覆盖率, 本实验使用         Java 代码覆盖率收集
                 工具  (javac 编译器基于  Java 语言开发) JaCoCo  [39] , 对编译阶段的代码进行覆盖率的收集. 为了收集           HotSpot 的代
                 码覆盖率, 本实验对      OpenJDK 21 (build 21-internal-adhoc.quand.openjdk21) 进行编译, 并在编译时开启“-enable-
                 native-coverage”选项. 随后, 利用  Gcov [40] 和  Lcov [41] 来收集和分析每种方法在  HotSpot 上取得的代码覆盖率.
                    (3) 未知缺陷数量
                    本实验未知缺陷的数量同样包括编译和执行阶段检测到的未知缺陷数量. 为了评估                             LumiX  是否能检测出未
                 知缺陷, 本实验在测试对象的最新版本上运行              LumiX  进行测试. 对于在最新版本上发现的编译和执行不一致缺陷,
                 本实验将对测试程序进行约简, 最后将约简后的测试程序分别提交给对应开发人员. 最终, 根据开发人员的反馈来
                 判定  LumiX  检测到的缺陷是否为未知缺陷, 并统计其中被确认并修复的缺陷数量, 以评估 LumiX                       在检测未知缺
                 陷方面的有效性.
   18   19   20   21   22   23   24   25   26   27   28