Page 166 - 《软件学报》2026年第7期
P. 166
宋壹 等: 基于异常检查点植入的软件缺陷定位方法 2851
有遵循软件开发最佳实践设置完备的异常处理机制 [22] , 导致源代码中仅含有少量甚至不含异常处理语句的情况
十分常见 [23,24] . 例如, 对 Java 社区中流行的数学计算项目 Math 核心包中的 12 363 行代码进行扫描, 未找到开发者
设置的异常处理代码. 由此可见, EXPECT 方法在真实开源社区的软件系统中应用能力有限, 其较高的缺陷定位能
力会因稀疏或缺失的异常处理语句而严重受制, 使得异常触发信息这一高效的缺陷定位源数据难以在广泛真实的
调试环境中发挥作用.
为此, 本文提出一种基于异常检查点植入的软件缺陷定位方法 INSPECT (inserted checkpoint-based fault
localization), 将 EXPECT 应用范围扩展至不含异常处理语句的错误程序. 具体而言, 首先向待测错误程序中以特
定的规则、密度和粒度, 自动植入 Try-catch 块作为临时检查点, 在其上记录程序运行过程中的异常触发信息, 作
为后续缺陷定位的主要信息源; 然后基于程序历史版本、不同开发分支或突变策略等得到失败测试用例的通过执
行, 与失败执行的异常触发信息进行比对以找到程序执行状态的分歧点; 接下来基于对分歧点的分析设计一种新
的程序语句风险值计算方法, 得到每条语句的风险值, 并进一步应用行级缺陷定位技术对上述风险值进行精化, 缓
解因多条语句共享同一风险值而造成的 Tie 问题; 最后将程序语句按精化后的风险值进行排序, 作为 INSPECT 方
法的输出. 在 Defects4J 数据集的 540 个错误程序版本上对方法进行验证, 结果表明, 相较于当前该领域的最优方
法, INSPECT 在 EXAM_Best、EXAM_Average 和 EXAM_Worst 指标上的提升幅度分别为 95.25%、55.92% 和 16.65%
(模拟缺陷), 以及 93.39%、57.54% 和 13.92% (真实缺陷), MRR 指标的提升幅度为 311.47% (模拟缺陷) 和 283.31%
(真实缺陷).
本文工作的数据及代码在 GitHub 上开源, 访问地址为: https://github.com/yisongy/INSPECT_Repo.
1 背景知识及 EXPECT 方法介绍
本文所提 INSPECT 方法利用程序异常触发信息作为主要数据源, 实现更加准确的代码行级缺陷定位. 下面就
相关概念、基本知识, 以及前期所提 EXPECT 方法予以介绍.
1.1 软件缺陷定位任务及所用信息源
软件质量保障一般分为软件测试和软件调试两个阶段 [25,26] . 在测试中, 动态测试因其较高的准确性和较低的
误报率而被广泛采用 (如无特殊说明, 本文后续的软件质量保障均在动态环境下讨论), 其执行测试用例并通过比
对程序实际输出和预期输出是否相同, 将测试用例划分为通过测试用例和失败测试用例, 失败测试用例揭示了程
序中缺陷的存在 [27,28] . 调试过程则负责对缺陷进行底层代码层面的定位 (软件缺陷定位任务), 进而开展修复 [29] . 可
见, 缺陷定位在整个软件质量保障过程中处于承上启下的位置, 直接影响软件正常功能的恢复. 根据软件测试调试
领域 PIE (propagation, infection, execution) 模型 [30] , 软件底层的缺陷只有感染到中间的运行状态, 才能外在表达为
表层可观测的程序失效 (即失败测试用例). 根据此模型可以得到, 软件缺陷定位任务实际上以测试阶段的失败测
试用例为入口, 通过挖掘并分析程序运行的中间状态, 找到底层代码中导致上述表层失效的根因.
当前, 基于频谱的缺陷定位技术 SBFL 和基于突变的缺陷定位技术 MBFL 应用最为普遍. SBFL 技术将程序
运行覆盖信息作为程序运行中间状态的代表数据, 将测试用例运行过程中对程序语句的覆盖情况记录为与语句数
等长的二进制向量 (1 代表覆盖, 0 代表未覆盖), 然后基于“被越多失败测试用例覆盖、越少通过测试用例覆盖的
程序语句应具有越高的含缺陷风险”思想, 将该思想数学化表达为程序语句风险值计算公式, 进而得到程序语句的
风险值排序列表作为方法输出 [31−33] . MBFL 技术同样以通过和失败测试用例作为分析对象, 其对程序语句进行随
机突变, 然后基于“在含有缺陷程序语句上的突变更有可能使失败测试用例变为通过, 在不含有缺陷语句上的突变
更有可能使通过测试用例变为失败”思想, 设计能够体现这一思想的数学化公式来为程序语句计算风险值, 最后返
回风险值排序 [34−36] . 尽管上述两类技术均在缺陷定位领域十分经典, 其分别具有不同的短板. 具体而言, SBFL 技
术收集的程序执行覆盖信息往往过于庞大, 使得该方法具有较高的运行成本; 此外, 覆盖信息只能从浅表的角度反
映程序运行时的中间状态, 使得许多程序语句可能具有完全相同的覆盖信息, 它们将被赋予相同的风险值而无法
被区分开 (具有相同风险值的语句绑定形成“Tie”). 特别是当真正含有错误的语句处于 Tie 中时, 缺陷定位的有效

