探索Delta Debugging:自动化调试的奥秘
1. 问题的提出与初步尝试
在软件开发中,确定一个更改是否依赖于另一个更改是一个难题。如果没有复杂的多版本程序分析工具,这个问题几乎难以解决。
尝试不同的更改顺序显然不可行,8721个单独的更改有8721!种不同的排序方式,根本无法全部测试。而尝试所有子集的情况稍好一些,8721个更改有$2^{8721}=10^{2625}$种可能的子集,测试数量比排序方式少很多,但仍然是一个巨大的数字。
于是,采用分治法成为了一个思路。可以先将更改的前半部分应用到gdb 4.16源代码中并进行测试。如果ddd失败,就知道导致失败的更改在前半部分;如果没有失败,就继续在后半部分中搜索。每次测试都将搜索空间缩小一半,最终找到导致失败的更改。然而,当应用一组更改导致代码不一致时,就不知道该如何处理了。
2. 自动查找失败原因
经过三个月的思考,终于想出了一个解决方案。其推理过程如下:
- 应用一半的更改获得一致构建的机会很小,跳过依赖更改的风险太高。但如果获得了一致的构建(或“已解决”的结果),就可以很快缩小更改集。
- 另一方面,逐个应用单个更改获得有意义结果的机会要大得多,特别是当被更改的版本已经是一致的时候。例如,更改一个单一的函数,除非其接口发生变化,否则很可能会得到一个可运行的程序。但逐个尝试更改仍然需要很长时间。
因此,采取了一种折中的方法:从将更改集分成两部分开始。如果两部分更改都不能得到可测试的构建,就将更改集分成四个子集,然后将每个子集分别应用到gdb 4.16源代码中。此外,还会从gdb 4.17源代码中撤销该子集(通过将该子集的补集应用到gd
超级会员免费看
订阅专栏 解锁全文
2695

被折叠的 条评论
为什么被折叠?



