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

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


                 语言新特性的测试依然存在局限性, 特别是长期遗留缺陷的覆盖不足. 此外, 这也进一步强调了增强对引入新特性
                 测试的必要性. 从表      5  中可以看出, LumiX   不仅可以检测出      Java  编译器中新特性相关的缺陷, 而且可以检测出
                 JVM  中的与新特性相关的未知缺陷. 这表明新特性相关缺陷不仅仅局限于编译器的解析过程中, 同样会出现在运
                 行时. 同时, 这也表明了     LumiX  采用双层差分测试的有效性.

                                                 表 5 确认及修复的未知缺陷

                            编号       缺陷ID       测试对象         影响版本        影响功能/特性         状态
                             1      Bug #3789     ECJ       OpenJDK 8       JEP 259    Confirmed
                             2      Bug #3790     ECJ       OpenJDK 21      JEP 126    Confirmed
                             3      Bug #3792     ECJ       OpenJDK 21      JEP 126     Fixed
                             4      Bug #3826     ECJ       OpenJDK 8      Compiler    Confirmed
                             5      Bug #4031     ECJ       OpenJDK 21      JEP 378     Fixed
                             6      Bug #21417   OpenJ9   OpenJDK 11, 17, 21  Runtime  Confirmed
                             7      Bug #21419   OpenJ9   OpenJDK 11, 17, 21  JEP 264   Fixed
                             8      Bug #21872   OpenJ9     OpenJDK 21       JIT       Confirmed
                             9      Bug #21886   OpenJ9     OpenJDK 21      JEP 121     Fixed
                             10     Bug #21931   OpenJ9     OpenJDK 21      JEP 264     Fixed
                             11    Bug #8356696   javac    OpenJDK 17, 21   JEP 181    Confirmed
                             12    Bug #8356989  HotSpot    OpenJDK 21      JEP 431     Fixed

                    接下来, 本实验通过两个具体的例子来进一步说明                LumiX  在检测新特性未知缺陷方面的有效性.
                    图  11  展示了  LumiX  生成的测试程序. 该测试程序成功检测出了             Java  编译器  ECJ 中的一个编译缺陷     (Bug
                 #3790). 具体来说, 该测试程序通过设置全局的反序列化过滤器工厂, 用于控制                    Java 反序列化过程中可接收的类.
                 为此, 该测试程序在第       3  行设置了一个   Lambda 表达式作为    setSerialFilterFactory  方法的参数. 该表达式包含两个
                 参数, 分别为反序列化时的上下文对象            (context) 和默认过滤器   (currentFilter). 随后, 在  Lambda 表达式中, 测试程
                 序在第   5  行通过对比   context 和  Object 类型是否相等, 来判断是创建一个新的过滤器还是使用默认的过滤器. 然
                 而, 该类型对比操作是错误的, 因为          context 是泛型类型, 而  Object 是引用类型. 但在使用不同的        Java 编译器  (即
                 javac 和  ECJ) 对该测试程序进行编译时, javac 正确地报告了编译错误, 而           ECJ 则成功地编译了该测试程序, 并且
                 生成了一个错误的       class 文件. 需要注意的是, 图   11  中浅蓝色标记部分为      LumiX  向种子程序中插入的包含语言新
                 特性的代码片段. 其中, Lambda 表达式是在        Java 8 中引入的新特性, 而反序列化过滤器工厂          (java.io.ObjectInputFilter)
                 则是在   Java 9  中引入的新特性. LumiX  迭代地生成包含新特性的测试程序, 最终生成了触发了不同                   Java 编译器不
                 一致行为的测试程序. 经过进一步的分析, 本文向              ECJ 编译器的开发人员提交了该缺陷报告. 目前, ECJ 的开发人
                 员已经对该缺陷进行了复现和确认.

                                  1 private static final long serialVersionUID = 1L;
                                  2 public static void main (String[] args) {
                                  3   java.io.ObjectInputFilter.Config.setSerialFilterFactory ((context, currentFilter) → {
                                  4     …
                                  5     if (context.getClass() == Object.class) {  //҂࡙ಸো྘ؓб
                                  6       return ObjectInputFilter.Config.createFilter(“com.example.*;!*”);
                                  7     }
                                  8     return currentFilter;
                                  9   });
                                  10  try {
                                  11    …  //ڭۂഈඍս઒
                                  12  } catch (Exception e) {e.printStackTrace();}
                                  13 }
                                               图 11 ECJ 编译器缺陷    (Bug #3790)

                    图  12  展示了  LumiX  生成的测试程序. 该测试程序成功检测出了           Java 虚拟机  OpenJ9  中的缺陷 (Bug #21419).
                 其中, 蓝色标记的代码区域为         LumiX  生成的新特性代码片段, 该代码片段中           String.Logger 是  Java 11  中引入的新
   22   23   24   25   26   27   28   29   30   31   32