Page 111 - 《软件学报》2025年第7期
P. 111
3032 软件学报 2025 年第 36 卷第 7 期
4.4 RQ4: 根因-症状-位置之间的内在联系
4.4.1 根因-症状之间的内在联系
表 3 展示了缺陷在不同症状和根因下的数量. 作为最普遍的缺陷根因, 逻辑错误最主要的症状是结果错误, 占
比 57.63%. 与崩溃缺陷不同, 结果错误类别的缺陷只有在特定的测试预言才能被捕获. 因此, 针对代码逻辑错误,
特别是优化逻辑错误设计相应的缺陷检测方法并设计细粒度的测试预言以捕获更多此类缺陷依然存在挑战. 对于
张量形状错误、API 误用、类型问题和异常处理错误这 4 类较为常见的缺陷类型, 他们最主要的症状为崩溃. 对
于这几类缺陷, 崩溃仍然是一种简单且有效的测试预言.
表 3 缺陷在不同症状与根因下的数量分布
根因 崩溃 结果错误 构建失败 性能问题 未报告 挂起 总计
逻辑错误 41 69 1 5 1 2 119
张量形状问题 73 8 0 3 2 0 86
API误用 42 18 1 10 6 2 79
类型问题 50 18 1 1 4 1 75
异常处理错误 51 10 1 3 1 3 69
配置错误 4 1 29 3 2 1 40
赋值错误 20 10 1 0 4 0 35
并发问题 14 9 1 2 2 2 30
不兼容 17 2 4 1 1 0 25
数值计算错误 10 13 0 0 1 0 24
注册错误 10 1 2 0 0 1 14
拼写错误 6 1 1 0 1 0 9
其他 2 5 0 1 0 0 8
总计 340 165 42 29 25 12 613
此外, 基于缺陷症状分析其与根因的内在联系有助于开发者快速识别缺陷的根因、对缺陷进行定位, 从而减
少缺陷调试时长. 从表 3 可以看出, 构建失败缺陷的根因主要为配置错误和不兼容问题. 这类缺陷主要由于配置文
件存在的错误引起的, 本文提供的数据集可以促进构建失败自动修复 [42] 的未来研究. 性能问题和挂起是两种调试,
定位难度极高的缺陷类别. 这两类缺陷的根因主要和逻辑错误、API 误用和异常处理错误相关. 这些发现有助于
加速开发者对缺陷的调试与定位过程.
发现 8. 在 DL 编译器中, 逻辑错误更容易引起错误的编译结果; 而张量形状错误、API 误用、类型问题和异
常处理错误常致编译过程崩溃. 构建失败多源于配置错误和不兼容问题; 性能下降和挂起错误则多由逻辑错误、
API 误用和异常处理不当所致.
4.4.2 根因-位置之间的内在联系
表 4 展示了 DL 编译器缺陷在不同根因和位置下的数量分布. 由于存在部分缺陷无法分类到 DL 编译器 3 个
阶段中的任何一个阶段 (比如, 编译安装 DL 编译器所使用的配置文件中的缺陷), 因此关于缺陷位置分布仅分析
可以分类到这 3 个阶段的缺陷. 由表可知, 逻辑错误出现在 Low-level IR 转换阶段的数量显著高于模型加载和
High-level IR 转换阶段. Low-level 转换阶段比前两个阶段有着更为复杂的代码逻辑, 尤其是优化相关的代码逻辑.
具体来说, 模型加载阶段实现了将 DL 框架中算子运算逻辑转换成 High-level IR, 由于存在 DL 框架中算子实现的
代码逻辑作为参考, 所以此阶段的代码逻辑实现起来较为简单. 同时, 相比较 High-level IR 转换阶段抽象程度更高
的代码逻辑, Low-level IR 转换阶段涉及更底层、更具体的操作, 例如寄存器分配、指令选择和优化等. 这些细粒
度的硬件特性相关信息提高了 Low-level IR 转换阶段的逻辑难度, 从而更容易引入逻辑错误.
此外, 从表 4 中可知, 90% 的并发缺陷都发生在 Low-level IR 转换阶段. 目前对 low-level 转换阶段的测试工
作仅有 Tzer [37] 一项, 其并没有检测到任何并发缺陷, 因此我们需要在测试 Low-level IR 转换过程中考虑到并发可
能引起的缺陷. 此外并发缺陷触发条件复杂度高, 复现难度大, 与运行时环境关系密切, 因此需要针对并发问题设

