论文部分内容阅读
如何提高程序正确性是软件工程领域的一个核心问题。由于软件系统的复杂性以及程序缺陷的多样性,尚不存在普适的方法能保证程序绝对正确。一旦缺陷在程序运行中引发故障,则需要通过程序调试定位并修复缺陷。实际的程序调试需要大量人工参与,以交互和迭代的方式进行,其开销约占软件开发和维护成本的50%以上。因此,提高程序调试的效率有助于提升程序正确性,并能显著降低软件开发和维护成本。鉴于程序调试的重要性,针对当前调试技术效率低下的问题,本文以提高程序调试技术的有效性和实用性作为目标,着眼于实际的交互式和迭代式调试场景,以程序分析和机器学习相结合作为主要途径,提出一套贯穿整个调试过程的新型程序调试技术。根据调试过程各阶段的特点,本文重点研究静态缺陷检测、静态和动态程序切片、基于日志和断点的交互式调试以及自动代码推荐等关键问题。首先,针对静态缺陷检测误报率过高的问题,本文提出控制流图的精化和扩展方法,使其能更好支持静态警告的筛选和排序,在调试开始阶段为调试人员提供更准确的缺陷警告信息。在控制流图精化方面,本文首次提出利用机器学习发掘分支关联以探测不可达路径的方法。通过程序插装搜集动态分支数据,采用关联规则学习挖掘程序分支的潜在关联,并通过评估与潜在分支关联的一致性检测程序路径可达性。该方法无需分析复杂路径条件,适用于规模较大含有复杂分支谓词的程序,能探测传统方法难以探测的不可达路径。在控制流图扩展方面,本文主要研究控制流图概率化。针对现存方法不适用于面向对象程序中的虚函数调用的问题,首次提出根据静态程序特征预测虚函数动态调用频率的方法——Festival。基于训练程序集合,Festival一方面提取用于表征程序设计意图的特征值,另一方面获取虚函数调用频率,基于两方面数据构建人工神经网络模型,刻画特征值与频率之间的关系。对于有待预测频率的测试程序,Festival仅需提取其静态特征作为模型输入,模型输出即为调用频率估计值。Festival弥补了现存方法无法应用于面向对象程序的缺点,且无需运行待预测程序,不依赖于输入数据的质量,从而有效克服动态分析方法的共有局限性。然后,在辅助交互式调试方面,本文针对当前常用工具(日志和断点)需消耗大量人力的缺点,提出自动化的分析、改进和生成技术。在日志分析方面,总结出日志使用的两个主要问题:1)冗余日志过多和2)关键日志缺失,首次提出从日志文件提取动态信息与传统静态程序切片相结合的日志切片技术,并基于日志切片提出日志精化技术。日志切片可削减冗余日志,同时产生更精简的程序切片。日志精化自动选择程序位置插入新日志语句,弥补现有日志中缺失的关键信息。另外,针对程序切片计算复杂度较高难以应用于交互式调试过程的问题,本文创新性的提出将程序切片过程分为离线和在线两个阶段。离线阶段进行各类静态程序分析并存储分析结果,在线阶段基于离线分析结果实时计算程序切片,从而大幅度缩短调试人员等待时间,使得日志切片可应用于交互式调试。同时,本文采用增量式和需求驱动式的数据流分析算法,确保离线分析结果与最新程序版本之间的一致性。除日志分析之外,本文结合最近邻搜索、动态程序切片和内存图分析技术,提出断点自动生成方法,节省手工设置断点的工作量。其中,最近邻搜索和动态程序切片用于自动选取断点设置位置,而针对特定程序位置选择特定时机进行内存图分析和生成条件断点的方法为本文首创。自动生成的断点能同时提示与缺陷相关的语句和程序状态,以调试人员熟悉的形式提供全面的辅助信息。最后,在缺陷修复方面,提出以实时代码推荐的形式解决由于程序员对代码掌握不足所导致的修复效率低下的问题。本文首次指出API参数推荐的重要性,并提出基于程序分析和数据挖掘相结合的解决方案——Precise。根据大规模实际程序的数据分析,提出一组经验性规则,有效限定候选参数的搜索空间,使得Precise具备可行性和实用性。通过对训练程序代码的分析、抽象和转换,Precise预先构建参数使用实例数据库。针对各个参数推荐请求,Precise根据请求上下文,使用最近邻搜索算法从数据库中获取相似上下文中的抽象参数使用模式并进行具体化,实时提供具有适应性的参数推荐。选取API参数是使用API的重要组成部分,而现有代码推荐方法仅关注API方法推荐,因此Precise填补了代码推荐领域的一项空白。另外,在构建Precise过程中获得的实证性调研结果为后续相关工作提供了有价值的参考信息。