论文部分内容阅读
多线程并发软件中,并发程序执行行为的不确定性和复杂性,使得并发程序中的并发缺陷被成功捕获的概率很小,并且很难再现。而并发缺陷一旦发生,将造成难以估计的损失。对于并发缺陷的人工修复不仅耗费人力,同时很难保证修复的正确性。因而设计并实现一个高质量的自动化修复工具,帮助开发人员修复这些并发缺陷变得至关重要。 对于并发缺陷的修复,现有的自动修复方式主要通过加保护锁的方式,使得缺陷中的线程无法并发执行,从而规避死锁以及原子性缺陷发生。但是这样的修复方式很容易引入新的死锁(资源死锁或通信死锁),同时可能会降低程序运行的效率和性能。 针对死锁,本文提出一种基于Pre-Acqusition的死锁修复策略:DFixer。DFixer只挑选死锁中的其中一个线程,将该线程中的第二个锁提取到第一个锁的位置并与第一个锁同时获取,打破死锁发生的必要条件,从而修复死锁。为了确保修复的过程中不引入新的死锁,DFixer对于执行修复操作的线程进行了严格的挑选,并通过上下文相关变量进行逻辑控制,避免修复过程中引入新的锁序从而保证DFixer修复的正确性。 针对原子性缺陷,本文提出了一种可适配性选择的原子性缺陷修复工具:αFixer。αFixer考虑了实际原子性缺陷中的代码结构,提供了调整现有锁和添加新的保护锁两种修复方式,在实际修复过程中,αFixer会根据代码结构进行适配性的选择修复方式。如果原有程序中存在现有锁保护相关变量的访问,那么αFixer通过调整锁保护范围的方式进行修复;如果不存这样的保护锁,αFixer会添加一个相同可见性的保护锁进行缺陷修复,很好的解决了修复过程中过度序列化造成的性能下降问题。同时αFixer结合了DFixer中提出的Pre-Acquisition操作,避免了在修复过程中引入死锁的问题。 在大型真实的并发程序数据集中进行了验证实验后,实验数据表明,DFixer和αFixer能够修复并发程序中的死锁和原子性缺陷,并且保证在修复过程中不引入新的死锁问题,另外DFixer和αFixer能够避免引入较大的额外时间开销,同时提供更具有可读性的修复代码。