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

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


                 性可能受到严重威胁. MBFL       技术依靠程序突变得到大量变体, 对于生成的变体均需重新编译执行, 时间和空间成
                 本均十分可观, 且其有效性同样受到           Tie 问题的影响. 近期, 一种基于语义的缺陷定位技术              SmartFL  被提出  [17] , 其
                 对程序语义信息、静态分析信息与动态执行跟踪信息进行综合建模, 采用基于概率的方法为程序语句预测风险值
                 以实现缺陷定位, 该技术已被证实效果超过了              SBFL  和  MBFL  技术, 展现了语义信息用于分析程序运行中间状态,
                 进而定位缺陷的潜力. 尽管如此, 该方法所采集语义信息的规模仍与程序执行跟踪信息的规模高度相关, 当大量程
                 序语句均被覆盖时, SmartFL     所用语义信息的大小可能和传统覆盖信息接近.
                    综上所述, 现有主流缺陷定位技术均面临着所用信息源庞大、难以精确对缺陷位置进行分析的不足. 因此, 一
                 个重要问题是如何找到一种能够有效在表层执行失效和底层缺陷根因之间建立起链接, 但又具有相对较小规模的
                 程序运行中间状态信息源, 以开展更加高效的缺陷定位.
                  1.2   程序异常处理机制
                    异常是一项主要用于处理程序运行时事件的机制                  [37] . 在软件程序运行过程中, 可以在程序执行至特定代码位
                 置且符合特定条件时抛出异常, 并由开发者设置异常处理代码对该异常进行捕获, 进而分析导致异常抛出的原因,
                 调整程序后续的执行策略. 异常处理机制设计的主要初衷之一, 是能够准确地记录并报告程序运行时的中间状态,
                 为后续可能的软件质量保障活动提供信息, 以帮助提高软件程序的可靠性. 异常所表现的抛出和未抛出行为是观
                 察程序执行中间状态的有效信息, 其具有简单、轻量级等特点. 因此, 结合前文所述                         PIE  模型的定义, 异常触发信
                 息具备作为观测程序运行中间状态的信息源, 帮助更有效地建立“表层执行失效→中间运行状态→底层缺陷根因”链
                 接的潜力.
                    以  Java 语言为例对异常处理机制进行介绍. 在           Java 语言中, 异常是   Thorwable 类的实例, 一般包括要求开发
                 者使用异常处理语句显式处理的            Checked Exception、允许开发者不做处理的      Unchecked Exception  和通常会导致
                 所在线程终止运行的        Error. 其中, Checked Exception  指受检查的异常 (如  IOException  和  FileNotFoundException
                 等), 除非在方法声明后使用        throws 关键字标明对应方法中可能抛出的异常类型, 否则必须使用                 Try  代码块捕获并
                 处理; Unchecked Exception  指不受检查的异常 (如   ArithmeticException  和  ClassCastException  等), 在  Java 语言中,
                 除通过   throw  关键字抛出指定类型的异常以外, 部分语句在执行时也可能按照编译器的规则抛出异常, 如除零异
                 常和空指针访问异常等; Error 指错误 (如        OutOfMemoryError 和  StackOverFlowError 等), 由于此类异常通常代表
                 程序运行时出现较为严重的错误, 开发者往往不对其进行捕获和处理                      [38,39] . 当异常被抛出时, 其可以被最近的异常
                 处理代码 (即   Java 中的  Try  代码块) 捕获, 并根据紧跟在    Try  代码块后的   catch  代码块中指定的异常类型来匹配由
                 开发者设计的异常处理逻辑, 然后依照对应逻辑进行如打印异常相关日志、执行特定业务逻辑或终止线程运行等
                 异常处理过程.
                  1.3   前期所提出基于异常信息的缺陷定位方法           EXPECT
                    为了验证程序异常信息用于缺陷定位任务的潜力, 于前期进行了一项探索性实验. 以                           GitHub  开源社区中广泛
                 使用的   Gson  项目  [40] 为分析对象, 将该程序自带的异常处理语句作为观测程序运行中间状态的窗口 (称为“检查
                 点”), 记录在检查点上显现的异常触发与否信息              (触发/未触发) 和执行跟踪       (测试执行的所有程序语句), 将以上两
                 项信息合称为“异常触发流”. 基于程序突变技术生成                Gson  的  40  个缺陷版本, 在缺陷版本和原始无缺陷版本上分
                 别运行单个失败测试用例, 分别得到该失败测试用例在失败执行和通过执行中的异常触发流, 进行比对以找到“分
                 歧点” (即最先显现出失败执行和通过执行异常触发流差异的检查点). 结果发现, 在                       80%  的缺陷版本中, 缺陷语句
                 都位于分歧点和上一个最近的检查点之间. 这一现象表明了程序异常触发信息在定位缺陷方面具有良好的潜力.
                 基于该探索性实验的结果, 提出了一种基于异常触发信息的缺陷定位方法                         EXPECT. 该方法以待测错误程序和其
                 对应的失败测试用例为输入, 首先为错误程序生成替代版本使得失败测试用例在其上能够变为通过, 然后在错误
                 程序和其替代版本上分别执行失败测试用例, 以获得该失败测试用例的失败执行和通过执行; 接下来, 基于程序中
                 原先自带的异常处理语句, 分别在上述失败执行和通过执行中记录得到异常触发流, 并通过比对找到两组信息开
                 始体现差异的分歧点, 以该分歧点的位置为依托确定错误语句的潜在范围; 最后引入行级缺陷定位技术, 为范围内
   162   163   164   165   166   167   168   169   170   171   172