Stack Overflow的缺陷代码特征分析与相似缺陷检测
2021-03-21亢振兴赵逢禹
亢振兴,赵逢禹,刘 亚
(上海理工大学 光电信息与计算机工程学院,上海 200093)
1 引 言
软件代码缺陷审查与缺陷预测是研究人员持续关注的问题.代码缺陷审查主要是通过相关的审查方法,对于源代码中存在的缺陷进行审查,以此来发现源代码中可能出现的缺陷情况[1-3].文献[4]提出了一种高效的检测源代码中的安全漏洞的代码审查方法,对于源代码中的可操作的内容提取安全特性用于代码审查.文献[5]提出了对不同层次代码对象进行失效模式分析来代替使用传统检查单的代码审查方法.此外,在软件缺陷预测领域,研究人员利用深度学习挖掘软件源码中复杂的非线性特征进行缺陷预测,提出了许多缺陷预测模型[6,7].
在基于代码的缺陷审查与缺陷预测研究中,研究人员利用专业知识对源代码进行分析,通过对代码中特征的综合评判,以发现代码中存在的缺陷或有缺陷倾向的代码段[8].而实际上,在现有的软件缺陷跟踪系统中,已经积累了大量的历史缺陷代码信息[9,10],相同的缺陷在不同的软件项目也会重复出现,对这些缺陷代码信息的分析与研究对于发现软件中类似缺陷具有重要参考价值.例如:Stack Overflow是一个计算机领域较为流行的交流社区,人们可以在上面发帖提出问题或者回答他人的提问,经过长时间的发展,此交流社区中也积累了大量有关于代码缺陷的问答贴[10,11],这些帖子也称为缺陷报告,在Stack Overflow中大量的缺陷报告形成了庞大的数据集.缺陷报告除了文本外,还有大量的编程代码,这些代码是使用者在进行提问时提交的问题代码.因此,在Stack Overflow中包含了许多有关于缺陷代码的信息.如何通过对于已发现缺陷代码的特征研究,构建特征提取方法,利用这些缺陷代码特征,分析与检测其他源代码中存在的缺陷倾向,对于发现的疑似缺陷提前进行检测和处理,对开发人员在代码审查和测试等软件质量保证活动中的任务安排与资源分配有重要指导意义.
2 基于缺陷代码特征分析的疑似缺陷检测方法
基于缺陷代码特征相似缺陷检测的核心是对缺陷代码的特征提取.
本文首先对Stack Overflow中缺陷报告进行分析,得到缺陷类型以及该类型缺陷代码对应的特征,对不同缺陷类型的缺陷代码特征的提取和分析;随后,构建基于特征相似度的缺陷检测模型;最后,针对待检测的项目代码,利用基于特征相似度的缺陷检测模型,计算缺陷特征的相似度[12],根据相似度对于代码段的缺陷可疑度进行分析,确定该代码段是否含有某一类缺陷.
如图1所示为Stack Overflow的缺陷代码特征分析及相似缺陷检测方法的处理流程,该处理流程包括以下4步.
图1 基于缺陷代码特征分析的相似缺陷检测方法的 处理流程图Fig.1 Treatment of similar defect detection method based on defect code characteristic analysis flow chart
Step 1.缺陷报告聚类分析
对于软件缺陷分析的过程中,缺陷分类是必不可少的.通过缺陷分类一方面可以较为快速准确地定位同类相似缺陷,另一方面按类对缺陷进行分析,对于缺陷的研究更加方便和高效.
Step 2.不同缺陷类型的缺陷代码特征提取
针对不同缺陷类别下的几种不同缺陷模式,通过分析造成软件缺陷的原因,对不同的缺陷代码特征进行了分析,提出需要关注的缺陷代码特征,并给出特征提取的方法.
Step 3.构建基于特征相似度的缺陷检测模型
首先,针对某一缺陷类D下的第k个缺陷子类Dk,给出此缺陷子类的缺陷代码特征Tki(i=1,2,…,p),其中p代表缺陷代码特征的个数.缺陷代码特征Tki用向量Dki来表示:Dki=(w11,w12,…,wkp)其中权重wkp表示在数据集中第k个缺陷子类Dk的第p个缺陷特征的频率,wkp的值计算公式(1)所示:
(1)
其中,nkp表示第k个缺陷子类Dk的第p个缺陷特征出现的次数,∑Dnk表示缺陷子类Dk中所有缺陷特征出现的次数.
其次,利用得到的不同类别的缺陷代码的特征向量Dki以及待检测代码段检测到缺陷特征的情况向量,可以对待检测项目中的代码段进行缺陷特征相似度检测.计算公式如式(2)所示.其中bi取值如公式(3)所示.
Sim(Dki,V)=wk1b1+wk2b2+…+wkpbp
(2)
(3)
Step 4.确定代码段的缺陷可疑度
针对待检测的项目代码段N,以(Dki,V)作为参数,利用基于特征相似度的缺陷检测模型计算某一缺陷类别D的不同缺陷模式Dk的特征的相似度,相似度越大则该代码段含有此类缺陷的可疑度就越大.最后,将缺陷可疑度较高的代码段可优先进行人工审查,确定是否为缺陷代码.
3 Stack Overflow的缺陷报告聚类分析
在Stack Overflow中有大量的缺陷代码,为了有针对性的对于这些含有缺陷的代码进行研究与分析,对于Stack Overflow中的缺陷代码进行分类是必要的.
基于本文的研究内容,需要获取Stack Overflow的数据.Stack Overflow的数据集公开在Stack Exchange Data Dump(1)https://archive.org/download/stackexchange中.在本文研究过程中使用Stack Overflow数据集中名为“Posts.xml”的公开数据集,“Posts.xml”数据集包含从2008年7月-2018年9月的所有帖子的问答信息,每一篇帖子都会包含与帖子内容相关的标签,通过标签可以简单了解到帖子涉及的内容,标签的数量一般不超过5个.
如图2所示为Stack Overflow中的一个问题帖子,该帖子涉及到问题的标题(Title)、问题的描述(Body)、问题的标签(Tags),如:示例问题的标签为“Java”和“Java-8”.
图2 Stack Overflow中问题示例Fig.2 Example of posts on Stack Overflow
在缺陷报告中,缺陷报告的标题、缺陷的描述等文本信息和缺陷情况密切相关,也更加准确地反映不同缺陷之间的联系.因此,为了高效快速地对缺陷报告进行分类,对于每一个缺陷报告的标签、标题和正文的文本信息分别进行研究与探分析.本文的研究中,首先提取与本文研究内容相符合的标签;其次根据标签对与本文研究内容相关的缺陷报告进行筛选并对问题的文本信息进行提取;最后根据文本信息提取主题并将数据集中的缺陷报告分别分配到相应的主题中,以此结果作为缺陷报告聚类的结果.
3.1 标签提取方法
本文主要针对Java代码中缺陷的情况进行分析,因此,Tags中含有“Java”作为首要的查找条件.首先遍历数据集找到标签中含有“Java”的缺陷报告,此缺陷报告可列入本文初始数据集;其次如果Tags中不含有“Java”时,遍历数据集中缺陷报告的标题(Title)和描述(Body),若其中含有“Java”,则此缺陷报告可列入本文初始数据集;最后丢弃除此之外的不相关的缺陷报告.
3.2 缺陷报告文本提取方法
每一个缺陷报告包括标题、正文和其他描述信息.为了将缺陷报告聚类,需要提取缺陷描述的文本信息.缺陷描述的文本信息提取的步骤如下:
1)删除缺陷报告中含有标签的部分,提取缺陷报告中剩余的部分;
标签)部分、停用词、数字、标点符号和其他非字母字符等部分,提取缺陷报告中剩余的部分;
3)使用 Snowball词干分析器提取词汇的词干部分(例如,“effective”和“effects”提取的词干为“effect”),通过这个方法可以提取到词汇的词干部分,将相似的词汇统一为相同的形式.
在上述 3 个步骤之后,为了进一步提高分析的准确率,根据各个词干出现的次数对所有的词干项进行排序,研究主要选取出现次数较高的词干,而出现次数较低的词干不具有代表意义.因此本文将出现次数小于 10 次的词干丢弃,不作分析.
3.3 缺陷报告聚类分析
缺陷报告的聚类分析主要是对数据集通过LDA主题模型分析[13-15],然后将不同的缺陷报告分组到不同的主题中去,以此完成缺陷报告聚类分析.在 LDA 中,主题的数量 K 的选择是非常重要的,K值的大小决定了LDA主题模型提取主题的情况,对最终主题提取结果具有一定的影响.因此,通过分析文献[16]的方法,采用等梯度渐进搜索的方式,通过梯度渐进搜索获得K的最优值.
算法 1.等梯度LDA搜索最佳主题
输入:主题数量的搜索范围[Mintopic,Maxtopic];
梯度数组g;
缺陷报告数据集M
输出:最佳主题数量kbest、主题topic
算法描述:
1.初始趟数i=0,根据i的取值从g中选择对应梯度gi,按gi从搜索范围[Mintopic,Maxtopic]内选择一个等差数列k,等差数列的值为主题数量;
2.将M以及k中的每一项ki作为主题数量传入到LDA模型中进行训练,计算Ccoh,并选取Ccoh最高的主题数ktop;
3.以ktop为中心、gi为半径,形成新的搜索范围[min(Mintopic,ky-gi),max(Maxtopic,ky+gi)],搜索的趟数加1;
4.重复步骤1-3,直到g遍历完;
5.输出Ccoh最高的主题数即为最佳主题数kbest;
6.将M以及最佳主题的数kbest传入LDA模型中进行训练;
7.输出主题topic;
算法1给出了利用LDA搜索最佳主题数量并的到最佳主题的过程.将搜索范围设为[1,10]的整数,即设置最佳主题的数量至少为1个,而至多为10个.此外,g是由一些整数按照从大到小的顺序排列组成.例如以2为梯度进行选择,所选的主题数数列为[1,3,5,7,9],通过一致性系数Ccoh的结果得到最佳主题数n为7,结果如图3所示.Ccoh计算使用gensim包中的CoherenceModel实现.Ccoh的大小决定了聚类的效果,对于后续的工作有重要的影响.当主题数量对应的一致性系数较高时,则说明在LDA主题模型中设置此主题数量可达到较好的结果.通过上述 LDA 的主题数渐进搜索的过程,可以为数据集所有缺陷报告找到适当数量的主题.
图3 最佳主题数搜素算法过程中一致性系数的分布Fig.3 Distribution of coherence coefficient in process of optimal topic number search algorithm
本文通过根据算法1搜索得到最佳主题,将缺陷报告分配到对应的主题中.通过对缺陷报告的聚类分析,发现有5类主题中包含了大量的缺陷报告,共占缺陷报告总数的85%.本文决定对于出现频率较高的这5类主题进行研究.
图4 各类缺陷所占的比例Fig.4 Proportion of various defects
根据每一个主题以及该主题相关的关键词,考虑到可读性和理解效果对于主题名称进行人工的归纳,本文把5类主题定义为:由数据操作造成的软件缺陷、由控制逻辑造成的软件缺陷、由计算过程造成的软件缺陷、由数据库造成的软件缺陷、由调用过程造成的软件缺陷,每一个主题名对应一类缺陷.如图4所示,给出了聚类分析的结果——各类缺陷所占比例.
4 缺陷类型以及缺陷代码特征分析
4.1 缺陷类型分析
本文对于上述分析中得到的5类出现频率较高的缺陷,结合造成缺陷的原因以及对于数据集中对应的代码段进行分析.首先,分别对于Stack overflow中5类出现频率较高的缺陷的数据,通过人工进行随机抽样分析,抽取的比例均为该类缺陷报告总数量60%,如表1所示,为用于分析的各类缺陷的数量.其次,对于各个类型下缺陷报告中的代码信息进行研究,以此列举出各类缺陷中可能出现的缺陷模式.如表2所示,给出了经过分析与研究得到的每一项缺陷类型以及类型的描述以及缺陷情况的列举.
表1 用于分析的各类缺陷的数量Table 1 Number of various types of defects used for analysis
表2 缺陷类型以及描述Table 2 Defect type and description
4.2 缺陷代码特征分析
本文需要对于不同缺陷类别下代码特征进行分析,由于篇幅,这里主要给出出现频率最高的缺陷—数据操作造成的软件缺陷进行研究.通过对缺陷代码数据集进行分析并参考大量相关文献,针对数据操作缺陷类别下的几种不同的缺陷代码情况,通过分析造成此种情况下软件缺陷的原因,对影响代码缺陷的特征进行了研究.针对数据操作缺陷的不同缺陷代码情况分别给出需要关注的缺陷代码特征,如表3所示,给出数据操作缺陷的几种情况以及特征和提取方法.
5 特征相似度的缺陷检测模型实证
为了进行全面的实验研究,使用在Stack Overflow上名为“Posts.xml”的公开数据集.该数据集包含从2008年7月-2018年9月的41782536个帖子.每个帖子均包括标题,正文和相关信息描述.为了进行特征相似度的缺陷检测模型,将得到的数据按6:4分成两部分,一部分缺陷报告的数据用于建立缺陷检测模型;另一部分缺陷报告的数据用于缺陷检测模型的验证.
表3 数据操作缺陷不同情况的特征Table 3 Characteristics of different conditions of data manipulation defects
本文主要针对数据操作缺陷构建缺陷检测模型.数据操作缺陷共包含3个缺陷子类:D1(Java空指针异常)、D2(Java数据类型转换异常)、D3(数组下标越界异常);对于每一缺陷子类都有相应的缺陷特征,例如:D1共有4个缺陷特征分别为声明类的对象但未实例化、声明类的对象但指向空值、字符串变量未初始化或初始化为null、接口类型的对象没有用具体的类初始化,分别用T11、T12、T13、T14表示,对应的缺陷特征向量分别为D11、D12、D13、D14.本文通过统计缺陷报告中各个缺陷特征出现的频率设定每个缺陷特征的权重.根据公式(1)计算每个缺陷特征的权重wkp.
为了评估本文提出的基于特征相似度的缺陷检测模型的有效性,本文从用于验证的40%的缺陷报告数据集中选取了属于数据操作缺陷的缺陷报告,并把这些缺陷报告根据其特征归到数据操作缺陷中的D1、D2、D3共3个子类.如表4所示,给出了用于验证的数据操作缺陷子类的数量.
本文使用Java开发语言开发完成了基于特征相似度的缺陷检测模型的开发程序.检测程序在windows平台上执行,其中内存为12GB、CPU为4×3.2GHz、硬盘容量为500GB,该程序将表3中的待验证的各类缺陷数据作为输入,使用本文提出的基于特征相似度的缺陷检测模型,循坏3次分别检测D1、D2、D3情况下相似度的值超过0.60时的缺陷,输出检测到的缺陷的数量.其中相似缺陷检测算法的执行时间为1908ms,内存消耗为40.3MB.最后人工审查检出缺陷的代码,计算准确率.如表5所示,为相似缺陷检测情况统计.
表4 数据操作缺陷子类的数量Table 4 Number of data manipulation defect subclasses
表5 相似缺陷检测情况统计Table 5 Similar defect detection statistics
从表5可以看出,本文提出的基于特征相似度的缺陷检测模型可以较准确地检测出不同类相似缺陷,尤其是对于数据操作缺陷子类D1,有较高的准确率.但是对于不同的缺陷子类可以检出缺陷的准确率不同,存在一定的误差.本文考虑造成准确率有高有低的原因和提取得到的缺陷特征关系较大,缺陷特征提取算法还可以进一步完善.
6 小 结
本文基于Stack Overflow中大量数据的分析提出了缺陷代码特征分析的相似缺陷检测模型.首先通过聚类分析将Stack Overflow中缺陷报告分到不同的缺陷类别中,然后对于数据操作缺陷的的几种情况给出相应的缺陷代码特征以及特征提取的方法,并且对于每一个缺陷代码特征,根据缺陷代码数据集计算其权重,最后,根据每种缺陷情况下每个缺陷代码特征的权重构建特征相似度的缺陷检测模型.
实验结果表明,本文提出的基于缺陷代码特征分析的相似缺陷检测方法可以检测到大部分相似缺陷.本文提出的方法对于开发人员在代码审查和测试等软件质量保证活动中的任务安排与资源分配有重要作用.但是本文提出的方法在对于每一种缺陷情况的缺陷代码特征的提取尚没能给出自动化方法,如果利用机器学习的方法对于缺陷代码特征分析并构建检测模型,对于诊断新代码中是否存在相似软件缺陷更有价值.