故障定位中的大语言模型

互联不一般哥 2024-04-13 21:36:55

Large Language Models in Fault Localisation

YongHao Wu,Zheng Li,JIE M.Zhang,Mike Harman,Yong Liu,

Beijing University of Chemical Technology, China

University College London, UK

University of Luxembourg, Luxembourg

引用

ACM Reference Format: Yonghao Wu, Zheng Li, Jie M. Zhang, Mike Papadakis, Mark Harman, and Yong Liu. 2023. Large Language Models in Fault Localisation. 1, 1 (August 2023), 23 pages.

论文:https://doi.org/10.48550/arXiv.2308.15276

摘要

大型语言模型(LLMs)在软件工程任务中展现潜力,尤其在故障定位方面备受关注。然而,对于LLMs在大型开源程序中故障定位能力的理解仍有限。本文研究了ChatGPT-3.5和ChatGPT-4在故障定位上的性能,并与现有技术进行了比较。研究发现,在有限代码上下文中,ChatGPT-4表现优异,但扩展到类级别时性能下降。此外,ChatGPT的可解释性不足。因此,尽管ChatGPT在某些条件下有效,但仍需进一步研究以充分发挥其在故障定位中的潜力。

1 引言

以ChatGPT为代表的大型语言模型(LLMs)在计算和数据科学领域引起了广泛关注,原因在于其广泛的应用和强大的性能。

在这些软件工程应用中,故障定位是软件系统调试过程中的关键阶段,是开发人员准确修复程序错误的先决条件。

然而,现有的故障定位技术存在显著的局限性。一个常见的不足在于缺乏可解释性分析,这阻碍了开发人员理解和准确判断故障定位结果的正确性。此外,许多故障定位技术在适应性方面存在困难,受到特定编程语言、测试用例质量或代码结构的限制,导致效率降低。

然而,现有研究未能系统地分析ChatGPT在故障定位方面的能力。因此,ChatGPT在故障定位方面的当前能力以及在实际开发场景中的潜在局限性仍然不明确。为了解决这个问题,本文全面研究了ChatGPT在故障定位方面的性能。研究结果揭示了ChatGPT在故障定位方面的当前优势和不足,并为未来的研究提供了启示。我们的研究旨在回答以下研究问题。

RQ1. ChatGPT在故障定位中的表现如何?

RQ1.1. 在FL度量标准下,ChatGPT的故障定位准确性与最新方法相比如何?

RQ1.2. ChatGPT在故障定位中的性能在重复实验中有多稳定?

RQ1.3. ChatGPT在故障定位中提供的解释是否准确?

RQ1.4. ChatGPT的故障定位结果与最新方法的结果有何重叠?

RQ2. ChatGPT的故障定位性能如何受到提示设计变化的影响?

RQ3. 提示中代码上下文的长度如何影响ChatGPT的故障定位性能?

我们的实证研究结果表明,ChatGPT的故障定位能力对提示中代码上下文的规模很敏感。在故障代码位置附近的有限代码上下文内,ChatGPT-4(Log)在所有基线方法中达到了最佳的故障定位效果和稳定性。然而,当代码上下文扩展到故障代码的类级别时,ChatGPT-4失去了其优势,表现不如最先进的故障定位方法。此外,尽管ChatGPT-4(Log)相比ChatGPT-4(Origin)提高了其故障定位结果的可解释性,但仍未达到令人满意的水平。此外,与现有的故障定位方法相比,即使是最先进的ChatGPT-4模型,在某些故障程序中仍表现出不足。

这项工作的贡献总结如下:

我们对大规模的开源程序Defects4J进行了全面的实证研究,以评估大型语言模型(LLM)在故障定位研究中的潜力。初步结果表明,在有限的代码上下文中,ChatGPT-4在故障定位准确性方面可以超越最先进的方法。我们总结了ChatGPT在故障定位方面的特点。我们的发现表明,动态执行信息有助于ChatGPT实现更准确和稳定的故障定位结果。我们识别了ChatGPT仍然存在的局限性,包括处理过长代码时的困难和对于开发人员需求而言,定位结果的可解释性不足。

2 实验设计

2.1 数据集

在本文中,我们从Defects4J中选择了六个大规模的开源Java项目进行实验分析。这些项目包括JFreeChart(Chart)、Google Closure compiler(Closure)、Apache Commons-Lang(Lang)、Apache Commons-Math(Math)、Mockito框架(Mockito)和Joda-Time(Time)。

表1总结了这些主题程序的详细信息。

表 1. 数据集的数据

2.2 基线方法

2.2.1 基于频谱的故障定位(SBFL)。

SBFL是一种调试技术,它利用通过和未通过测试用例的执行轨迹来估计程序元素发生故障的可能性。其核心思想是,与通过测试相比,故障元素更频繁地被未通过测试覆盖。SBFL技术通过计算每个程序元素的可疑度值来量化这一思想。

2.2.2 基于变异的故障定位(MBFL)。

MBFL通过利用程序变异体来定位潜在的错误。传统的MBFL会自动应用如替换操作符等变异操作来植入错误。这些变异后的程序(变异体)会接受测试套件的执行,以识别被测试用例杀死的变异体。通过比较原始程序和变异体之间的测试输出,MBFL将那些经常被杀死变异体影响的程序元素赋予更高的可疑度值。

2.2.3 基于语义的概率故障定位(SmartFL)。

SmartFL是一种新颖的语句级故障定位方法。它使用概率推理来建模程序元素发生故障的可能性。该方法结合了静态分析和动态执行轨迹,以估计程序值的正确性,而无需捕获完整的语义信息。SmartFL在有效性和可扩展性之间取得了平衡。

2.3 ChatGPT设置

本节详细描述了在我们的实证研究中如何利用ChatGPT进行故障定位的过程。

确定最优ChatGPT版本。鉴于我们实验规模较大,高效利用每个ChatGPT模型的最优版本至关重要。初步小规模实验表明,ChatGPT-3.5的网页界面和API之间结果相当。为提高效率,我们在所有ChatGPT-3.5的实验中采用了API。

相比之下,ChatGPT-4的API相对于其网页界面的表现一直较差。因此,为了评估ChatGPT-4的最具前景的能力,我们在实验中使用了其网页界面版本。由于实验耗时较长,我们跨越了多个版本——从ChatGPT 5月3日版到ChatGPT 8月3日版。

代码上下文。ChatGPT这样的大语言模型有令牌限制,这阻止了提交如Defects4J中那样的大规模代码库。我们通过提取包含程序中错误语句的函数来解决这个问题。这个函数在提示中提供了上下文,有效地缩小了ChatGPT定位目标函数内错误语句的代码上下文范围。

提示词设计。我们的方法涉及与ChatGPT-3.5和ChatGPT-4进行两轮全面的对话,针对每个目标函数。此外,在我们的实验中,我们分别比较了ChatGPT-3.5和ChatGPT-4在第一轮和第二轮对话中的故障定位性能。此外,我们在RQ2中进行了消融研究,以分析不同提示组件对最终故障定位结果的影响。

图 1. 提示词1的示例

ChatGPT-3.5和ChatGPT-4对Prompt1的响应分别表示为ChatGPT-3.5(Origin)和ChatGPT-4(Origin)。图2提供了ChatGPT-4对Prompt1的示例回答,该Prompt1针对的是根据边长确定三角形类型的函数。ChatGPT识别出第2行作为潜在错误,因为当前的"<"条件无法处理当两边之和等于第三边时的无效三角形情况。这个例子展示了ChatGPT通过分析代码逻辑和局限性来提供有理有据的故障定位的能力。

为了全面模拟人类程序员进行故障定位的过程,在得到Prompt1的初始故障定位结果后,我们使用Prompt2进行第二轮对话。这个提示在Prompt1的代码片段基础上增加了一个相应的失败单元测试案例和错误日志,如图3所示。

有了这些额外的上下文故障信息,Prompt2要求ChatGPT重新审查并改进其对Prompt1响应中提供的初步疑似故障位置。ChatGPT-3.5和ChatGPT-4对Prompt2的修改后输出分别表示为ChatGPT-3.5(Log)和ChatGPT-4(Log)。

结果收集。为了方便管理实验结果,我们指示ChatGPT以普遍认可的JSON格式提供故障定位输出。预期响应将遵循提示要求中指定的格式和内容。如果出现任何偏差,我们将持续重新提交提示,直到输出与给定规范一致。此外,Defects4J中的一些目标函数可能避免通过测试用例执行或不会触发异常,从而导致无法产生错误日志信息。在这种情况下,我们将利用第一轮对话的结果(ChatGPT-3.5/4(Origin))作为第二轮对话(ChatGPT-3.5/4(Log))的输入。

图 2. 提示词1的回答

图 3. 提示词2的示例

在得到ChatGPT提供的JSON结果后,我们解析JSON字符串,并按照Prompt1的指示,将JSON字符串中的前五个代码语句作为ChatGPT的故障定位结果。最后,我们可以使用这个结果来评估ChatGPT在TOP-1到TOP-5指标方面的性能。

降低随机性。鉴于ChatGPT输出的固有随机性,我们针对每个目标函数采用了严格的重复实验方法。本文中所有与ChatGPT相关的实验都独立进行了五次。然后,我们综合这些结果,计算TOP-N指标的平均值作为最终的故障定位结果。

2.4 故障定位准确性的度量

2.4.1 TOP-N指标

先前的研究表明,70%的开发者和测试人员只关注故障定位排名列表中的前五个程序语句。因此,我们利用广泛使用的TOP-N指标来评估故障定位技术的准确性。

2.4.2 威尔科克森符号秩检验

威尔科克森符号秩检验是一种稳健的统计分析方法,特别适用于数据不符合正态分布假设的情况。这种非参数检验方法通过比较配对观测值差异的正负秩,来判断两个相关样本是否来自相同的总体。

3 结果分析

3.1 RQ1:ChatGPT的有效性

RQ1.1:方法比较

表 2. 基于TOP-N 准则的故障定位结果

表2中的结果展示了最先进的SmartFL方法相较于传统的故障定位技术SBFL和MBFL的优越性。虽然ChatGPT-3.5 (Origin)和ChatGPT-3.5 (Log)在部分情况下实现了最优性能,但SmartFL在整体有效性方面设定了更高的当代基准。相比之下,ChatGPT-4 (Origin)和ChatGPT-4 (Log)在大多数情况下都超过了其他方法。

回答RQ1.1:在大多数故障定位任务中,ChatGPT-4,特别是ChatGPT-4 (Log)版本,表现优于其他基线方法。

RQ1.2:ChatGPT的稳定性

如表3所示,尽管由于随机性存在微小的波动,但比较性能方面呈现出一致的模式。重要的是,ChatGPT-4表现出了一贯的优越性,在所有五次重复实验中均位居榜首。

表 3. 重复实验的结果

为了进一步评估稳定性,我们提供了表4,对重复实验中观察到的方差进行了统计分析的总结。方差作为稳定性指标,值越低表示变异性越小,稳定性越高,从而提供了每种方法可靠性的见解。

由于出色的鲁棒性,在后续实验中,我们将主要使用ChatGPT-4(Log)作为代表ChatGPT方法的实验结果比较对象。

表 4. 重复实验的总体结果

回答RQ1.2:与ChatGPT-3.5 (Origin/Log) 和ChatGPT-4 (Origin)相比,ChatGPT-4 (Log)在多次评估中始终表现出优越的性能和低方差。

RQ1.3:ChatGPT的可解释性

根据现有的Java程序错误分类研究,我们可以将Defects4J中的所有错误分为三类:编译时(语义和语法)、逻辑和运行时(异常)。然而,在数据收集过程中,包含编译时错误的Defects4J版本已被过滤掉,因此不在本文的实验范围内。因此,本文的数据集仅包含逻辑和运行时错误。我们发现ChatGPT给出的原因中,除了逻辑和运行时错误外,还有两类误分类:不良代码味道和需要更多信息。总结起来,我们可以将ChatGPT给出的代码错误分为以下四个类别:

逻辑错误:代码中存在逻辑错误,包括算法实现不当、控制流设计缺陷、算术运算符误用或数据比较不正确等。

运行时错误:代码对Java函数、变量、方法参数和对象的验证不足,例如未检查空值或越界索引。

不良代码味道:代码执行正确并产生预期结果,但它违反了最佳编程实践,导致代码难以阅读和维护。

需要更多信息:ChatGPT认为该语句不正确,但无法确定原因,因此需要请求更多信息。

在本实验中,我们从RQ1.1的重复实验中提取了一个实验,然后将ChatGPT-4 (Origin)和ChatGPT-4 (Log)的JSON输出中故障语句的“原因”归类为这四个类别。该分类的结果如图4所示。

图 4. ChatGPT-4 的故障定位原因的分类

图4中的结果揭示了与ChatGPT-4(Log)相比,解释ChatGPT-4 (Origin)输出的挑战。由于ChatGPT-4 (Origin)的结果中有更高比例落入了“需要更多信息”的类别,这表明ChatGPT-4 (Origin)无法直接为故障定位提供有用的原因,并需要开发人员检查程序的其他部分,因此对其可解释性没有帮助。相比之下,ChatGPT-4(Log)利用错误日志和测试用例,更倾向于将原因归类为“逻辑错误”,因此它似乎比ChatGPT-4 (Origin)提供了更多的可解释性帮助。

根据我们的比较,ChatGPT-4(Log)在逻辑错误分类上的准确率更高。尽管ChatGPT-4(Log)相较于ChatGPT-4 (Origin)表现出了更高的分类准确率,但两者在改进前后的整体准确率仍然不尽如人意。

回答RQ1.3:ChatGPT提供的解释不准确。然而,通过引入额外的错误日志信息,可以显著提高可解释性。

RQ1.4:方法重叠

在本节中,我们进行重叠实验,以评估在RQ1.1的重复实验中,ChatGPT-4(Log)相对于其他方法平均表现更好、相当或更差的频率。

表 5. ChatGPT与其他方法之间的重叠

从表5可以看出,“更好”的值都大于“更差”的值,这意味着ChatGPT-4(Log)在更多程序版本上实现了更高的故障定位准确率,超过了所有基线方法。此外,ChatGPT-4(Log)和ChatGPT-4 (Origin)的“相等”值最高,这意味着这两种方法在更多情况下达到了相同的性能。另外,与SmartFL相比,ChatGPT-4(Log)在所有基线方法中具有最大的“更差”值,这意味着SmartFL在与其他基线方法相比时,在最多情况下超过了ChatGPT-4(Log)。

我们手动分析了在五次重复实验中,ChatGPT-4(Log)相对于SmartFL持续表现不佳的12个案例。这些案例中的大多数可以归因于缺失的逻辑,图5中展示了其中的一个典型案例。

图 5. ChatGPT-4(Log)表现不佳的示例

从图5可以看出,此类故障需要加入额外的逻辑代码来解决,而无需更改或删除原始程序中的现有代码。为了提高ChatGPT-4(Log)在故障定位中的有效性,未来的改进可以着重于增强其对此类缺失逻辑代码的理解和识别能力。

回答RQ1.4: 在更多情况下,ChatGPT-4(Log)实现了比所有基线方法更好的故障定位性能。

3.2 RQ2:提示词的影响

为了解答RQ3,我们进行了一项消融研究,以拆解ChatGPT-4的复杂故障定位系统。通过本节,我们旨在明确每个组件对整体性能的贡献。具体来说,我们专注于分析驱动ChatGPT-4故障定位能力的提示中的组件。

除了故障定位的基本必要要求外,我们还从Prompt1和Prompt2中提取了四个可选组件。它们分别是:在Prompt1和Prompt2中按怀疑程度降序排列语句的要求;在Prompt1和Prompt2中解释故障定位原因的要求;Prompt2中的错误日志信息;以及Prompt2中的测试用例信息。

因此,通过单独删除一个组件,我们创建了四个版本的消融提示并进行测试:

•:这个变体排除了Prompt1和Prompt2中要求ChatGPT按怀疑程度降序排列潜在错误语句的部分。

•:这个变体去除了Prompt1和Prompt2中解释当前故障定位结果背后的理由的需要。

•:这个变体从Prompt2中移除了错误日志,而Prompt1保持不变,与原始版本相同。

•:这个变体从Prompt2中移除了测试用例的内容,而Prompt1保持不变,与原始版本相同。

表6展示了这四种消融方法与原始ChatGPT-4(Origin)和ChatGPT-4(Log)的比较。

表6. ChatGPT-4在不同提示下的实验结果

此外,我们使用Wilcoxon符号秩检验进行了统计显著性分析,如表7所示。

表 7. 消融研究的p值

回答RQ2:提示中的每个组件都对ChatGPT-4的有效性做出了积极贡献。排除任何一个组件都会导致精度下降。其中,排除错误日志消息的影响最为显著。

3.3 RQ3:上下文的影响

为了研究代码上下文范围的影响,我们通过操纵提示中的上下文范围进行了两次对照实验。在第一个实验中,我们将上下文限制在包含错误语句的函数内的错误语句前后五行代码。

从表8中,我们可以发现ChatGPT-4(Log)在大多数情况下仍然保持着相当的优势。然而,随着代码上下文的减少,其他基线方法的效果也得到了提升。

在随后的实验中,我们将上下文扩展到包含错误代码的整个类。如果一个类包含跨不同函数的多个错误语句,则将整个类的代码用作单个提示中的上下文。扩展上下文实验的结果如表9所示。如表8所意外显示的那样,ChatGPT-4不再表现出优势。

表8. 限制上下文的实验结果

回答RQ3:ChatGPT的故障定位能力对提示中的代码上下文范围高度敏感。

表9. 扩展上下文的实验结果

4 相关工作

4.1 故障定位

为了协助开发人员定位故障,已经提出了多种方法。这些方法包括基于谱的故障定位(SBFL)、基于变异的故障定位(MBFL)以及基于深度学习的故障定位技术。

在传统的故障定位技术中,SBFL因其简单性、有效性和低计算成本而受到研究者的广泛关注。然而,尽管SBFL效率很高,但它的精确度却不如其他故障定位方法。

此外,基于变异的故障定位(MBFL)作为一种高精度的故障定位技术也受到了广泛关注。然而,该技术计算成本高昂,且传统的MBFL在通过变异操作模拟真实世界软件故障方面存在困难。

为了弥补这些局限性,近期的研究旨在通过融入额外的语义信息来提高定位精度。 SmartFL就是一个例子,它是一种基于概率模型的技术,它仅考虑值的正确性,而不是完整的语义。

随后,随着神经网络的广泛应用,深度学习在软件测试中的应用也激发了许多关于故障定位的研究,如Grace、FLUCCS和DeepFL。

随后,有人提出了一种基于图的表示学习技术,以提高基于覆盖率的故障定位效果。这种技术在Defects4J上显著超过了现有的故障定位技术。

尽管基于深度学习的故障定位方法(包括上述方法)显示出巨大的发展潜力,但它们通常只能定位到故障函数,而无法精确到具体的故障语句。因此,在本文中,我们没有选择这些技术作为基线方法。

4.2 软件工程中的大型语言模型

鉴于大型语言模型(LLMs)的突破性进展,研究者们开始探索LLMs如何协助开发者完成各种任务,包括:

代码修复:LLMs可用于生成提示,引导开发者提升代码质量,执行重构操作,或修复代码中的错误或缺陷。

需求获取:LLMs可用于生成提示,帮助开发者获取软件项目的需求并创建软件设计规格,如API规格、用户故事和UML图。

代码总结:LLMs可用于生成自然语言摘要,描述代码段的整体功能和设计意图。

故障定位:LLMs可用于生成提示,通过分析程序行为或输出来识别故障类型和位置。

5 有效性威胁

首先,ChatGPT的响应涉及一定程度的随机性,这可能对我们的结果的可信度构成潜在影响。为了缓解这一威胁,我们进行了五次相同的实验并计算了结果,力求保证我们结果的一致性和稳健性。因此,这一威胁被限制在了一定范围内。

其次,广泛应用于故障定位领域的Defects4J数据集可能是ChatGPT训练数据的一部分,从而可能引发数据泄露的问题。

6 对研究者和开发者的启示

为了充分利用LLMs的故障定位能力,研究者和开发者在数据预处理过程中应最大化关键内容的信息密度,并最小化无关内容。研究者应在提示中整合更多样化的数据,除了源代码外,还应包括测试用例、文档和监控数据等,以更贴近开发者实际调试过程。研究者和开发者应通过提示工程引导LLM优先处理最相关的内容。尽管ChatGPT-4可以在一定程度上协助开发者进行故障定位,但仍需要对其结果进行大量的手动验证。

7 结论

综上所述,本文系统地探讨了将ChatGPT应用于大型开源程序故障定位的潜力。

与现有的故障定位方法相比,ChatGPT-4在提示中的代码上下文受限的情况下,大多数情况下表现出色。然而,也观察到最先进的语句级故障定位方法SmartFL在相当多的情况下优于ChatGPT-4。此外,ChatGPT的故障定位性能对上下文范围高度敏感。

最后,从故障定位的可解释性角度来看,ChatGPT仍然未能达到令开发者满意的结果。因此,将ChatGPT用于故障定位仍然是一个需要进一步改进的研究领域,需要进一步的细化和研究,以真正发挥其在实际场景中的潜在优势。

转述:朱轶凡

0 阅读:0

互联不一般哥

简介:感谢大家的关注