亢振興,趙逢禹,劉 亞
(上海理工大學(xué) 光電信息與計(jì)算機(jī)工程學(xué)院,上海 200093)
軟件代碼缺陷審查與缺陷預(yù)測(cè)是研究人員持續(xù)關(guān)注的問題.代碼缺陷審查主要是通過相關(guān)的審查方法,對(duì)于源代碼中存在的缺陷進(jìn)行審查,以此來發(fā)現(xiàn)源代碼中可能出現(xiàn)的缺陷情況[1-3].文獻(xiàn)[4]提出了一種高效的檢測(cè)源代碼中的安全漏洞的代碼審查方法,對(duì)于源代碼中的可操作的內(nèi)容提取安全特性用于代碼審查.文獻(xiàn)[5]提出了對(duì)不同層次代碼對(duì)象進(jìn)行失效模式分析來代替使用傳統(tǒng)檢查單的代碼審查方法.此外,在軟件缺陷預(yù)測(cè)領(lǐng)域,研究人員利用深度學(xué)習(xí)挖掘軟件源碼中復(fù)雜的非線性特征進(jìn)行缺陷預(yù)測(cè),提出了許多缺陷預(yù)測(cè)模型[6,7].
在基于代碼的缺陷審查與缺陷預(yù)測(cè)研究中,研究人員利用專業(yè)知識(shí)對(duì)源代碼進(jìn)行分析,通過對(duì)代碼中特征的綜合評(píng)判,以發(fā)現(xiàn)代碼中存在的缺陷或有缺陷傾向的代碼段[8].而實(shí)際上,在現(xiàn)有的軟件缺陷跟蹤系統(tǒng)中,已經(jīng)積累了大量的歷史缺陷代碼信息[9,10],相同的缺陷在不同的軟件項(xiàng)目也會(huì)重復(fù)出現(xiàn),對(duì)這些缺陷代碼信息的分析與研究對(duì)于發(fā)現(xiàn)軟件中類似缺陷具有重要參考價(jià)值.例如:Stack Overflow是一個(gè)計(jì)算機(jī)領(lǐng)域較為流行的交流社區(qū),人們可以在上面發(fā)帖提出問題或者回答他人的提問,經(jīng)過長(zhǎng)時(shí)間的發(fā)展,此交流社區(qū)中也積累了大量有關(guān)于代碼缺陷的問答貼[10,11],這些帖子也稱為缺陷報(bào)告,在Stack Overflow中大量的缺陷報(bào)告形成了龐大的數(shù)據(jù)集.缺陷報(bào)告除了文本外,還有大量的編程代碼,這些代碼是使用者在進(jìn)行提問時(shí)提交的問題代碼.因此,在Stack Overflow中包含了許多有關(guān)于缺陷代碼的信息.如何通過對(duì)于已發(fā)現(xiàn)缺陷代碼的特征研究,構(gòu)建特征提取方法,利用這些缺陷代碼特征,分析與檢測(cè)其他源代碼中存在的缺陷傾向,對(duì)于發(fā)現(xiàn)的疑似缺陷提前進(jìn)行檢測(cè)和處理,對(duì)開發(fā)人員在代碼審查和測(cè)試等軟件質(zhì)量保證活動(dòng)中的任務(wù)安排與資源分配有重要指導(dǎo)意義.
基于缺陷代碼特征相似缺陷檢測(cè)的核心是對(duì)缺陷代碼的特征提取.
本文首先對(duì)Stack Overflow中缺陷報(bào)告進(jìn)行分析,得到缺陷類型以及該類型缺陷代碼對(duì)應(yīng)的特征,對(duì)不同缺陷類型的缺陷代碼特征的提取和分析;隨后,構(gòu)建基于特征相似度的缺陷檢測(cè)模型;最后,針對(duì)待檢測(cè)的項(xiàng)目代碼,利用基于特征相似度的缺陷檢測(cè)模型,計(jì)算缺陷特征的相似度[12],根據(jù)相似度對(duì)于代碼段的缺陷可疑度進(jìn)行分析,確定該代碼段是否含有某一類缺陷.
如圖1所示為Stack Overflow的缺陷代碼特征分析及相似缺陷檢測(cè)方法的處理流程,該處理流程包括以下4步.
圖1 基于缺陷代碼特征分析的相似缺陷檢測(cè)方法的 處理流程圖Fig.1 Treatment of similar defect detection method based on defect code characteristic analysis flow chart
Step 1.缺陷報(bào)告聚類分析
對(duì)于軟件缺陷分析的過程中,缺陷分類是必不可少的.通過缺陷分類一方面可以較為快速準(zhǔn)確地定位同類相似缺陷,另一方面按類對(duì)缺陷進(jìn)行分析,對(duì)于缺陷的研究更加方便和高效.
Step 2.不同缺陷類型的缺陷代碼特征提取
針對(duì)不同缺陷類別下的幾種不同缺陷模式,通過分析造成軟件缺陷的原因,對(duì)不同的缺陷代碼特征進(jìn)行了分析,提出需要關(guān)注的缺陷代碼特征,并給出特征提取的方法.
Step 3.構(gòu)建基于特征相似度的缺陷檢測(cè)模型
首先,針對(duì)某一缺陷類D下的第k個(gè)缺陷子類Dk,給出此缺陷子類的缺陷代碼特征Tki(i=1,2,…,p),其中p代表缺陷代碼特征的個(gè)數(shù).缺陷代碼特征Tki用向量Dki來表示:Dki=(w11,w12,…,wkp)其中權(quán)重wkp表示在數(shù)據(jù)集中第k個(gè)缺陷子類Dk的第p個(gè)缺陷特征的頻率,wkp的值計(jì)算公式(1)所示:
(1)
其中,nkp表示第k個(gè)缺陷子類Dk的第p個(gè)缺陷特征出現(xiàn)的次數(shù),∑Dnk表示缺陷子類Dk中所有缺陷特征出現(xiàn)的次數(shù).
其次,利用得到的不同類別的缺陷代碼的特征向量Dki以及待檢測(cè)代碼段檢測(cè)到缺陷特征的情況向量,可以對(duì)待檢測(cè)項(xiàng)目中的代碼段進(jìn)行缺陷特征相似度檢測(cè).計(jì)算公式如式(2)所示.其中bi取值如公式(3)所示.
Sim(Dki,V)=wk1b1+wk2b2+…+wkpbp
(2)
(3)
Step 4.確定代碼段的缺陷可疑度
針對(duì)待檢測(cè)的項(xiàng)目代碼段N,以(Dki,V)作為參數(shù),利用基于特征相似度的缺陷檢測(cè)模型計(jì)算某一缺陷類別D的不同缺陷模式Dk的特征的相似度,相似度越大則該代碼段含有此類缺陷的可疑度就越大.最后,將缺陷可疑度較高的代碼段可優(yōu)先進(jìn)行人工審查,確定是否為缺陷代碼.
在Stack Overflow中有大量的缺陷代碼,為了有針對(duì)性的對(duì)于這些含有缺陷的代碼進(jìn)行研究與分析,對(duì)于Stack Overflow中的缺陷代碼進(jìn)行分類是必要的.
基于本文的研究?jī)?nèi)容,需要獲取Stack Overflow的數(shù)據(jù).Stack Overflow的數(shù)據(jù)集公開在Stack Exchange Data Dump(1)https://archive.org/download/stackexchange中.在本文研究過程中使用Stack Overflow數(shù)據(jù)集中名為“Posts.xml”的公開數(shù)據(jù)集,“Posts.xml”數(shù)據(jù)集包含從2008年7月-2018年9月的所有帖子的問答信息,每一篇帖子都會(huì)包含與帖子內(nèi)容相關(guān)的標(biāo)簽,通過標(biāo)簽可以簡(jiǎn)單了解到帖子涉及的內(nèi)容,標(biāo)簽的數(shù)量一般不超過5個(gè).
如圖2所示為Stack Overflow中的一個(gè)問題帖子,該帖子涉及到問題的標(biāo)題(Title)、問題的描述(Body)、問題的標(biāo)簽(Tags),如:示例問題的標(biāo)簽為“Java”和“Java-8”.
圖2 Stack Overflow中問題示例Fig.2 Example of posts on Stack Overflow
在缺陷報(bào)告中,缺陷報(bào)告的標(biāo)題、缺陷的描述等文本信息和缺陷情況密切相關(guān),也更加準(zhǔn)確地反映不同缺陷之間的聯(lián)系.因此,為了高效快速地對(duì)缺陷報(bào)告進(jìn)行分類,對(duì)于每一個(gè)缺陷報(bào)告的標(biāo)簽、標(biāo)題和正文的文本信息分別進(jìn)行研究與探分析.本文的研究中,首先提取與本文研究?jī)?nèi)容相符合的標(biāo)簽;其次根據(jù)標(biāo)簽對(duì)與本文研究?jī)?nèi)容相關(guān)的缺陷報(bào)告進(jìn)行篩選并對(duì)問題的文本信息進(jìn)行提取;最后根據(jù)文本信息提取主題并將數(shù)據(jù)集中的缺陷報(bào)告分別分配到相應(yīng)的主題中,以此結(jié)果作為缺陷報(bào)告聚類的結(jié)果.
本文主要針對(duì)Java代碼中缺陷的情況進(jìn)行分析,因此,Tags中含有“Java”作為首要的查找條件.首先遍歷數(shù)據(jù)集找到標(biāo)簽中含有“Java”的缺陷報(bào)告,此缺陷報(bào)告可列入本文初始數(shù)據(jù)集;其次如果Tags中不含有“Java”時(shí),遍歷數(shù)據(jù)集中缺陷報(bào)告的標(biāo)題(Title)和描述(Body),若其中含有“Java”,則此缺陷報(bào)告可列入本文初始數(shù)據(jù)集;最后丟棄除此之外的不相關(guān)的缺陷報(bào)告.
每一個(gè)缺陷報(bào)告包括標(biāo)題、正文和其他描述信息.為了將缺陷報(bào)告聚類,需要提取缺陷描述的文本信息.缺陷描述的文本信息提取的步驟如下:
1)刪除缺陷報(bào)告中含有標(biāo)簽的部分,提取缺陷報(bào)告中剩余的部分;
標(biāo)簽)部分、停用詞、數(shù)字、標(biāo)點(diǎn)符號(hào)和其他非字母字符等部分,提取缺陷報(bào)告中剩余的部分;
3)使用 Snowball詞干分析器提取詞匯的詞干部分(例如,“effective”和“effects”提取的詞干為“effect”),通過這個(gè)方法可以提取到詞匯的詞干部分,將相似的詞匯統(tǒng)一為相同的形式.
在上述 3 個(gè)步驟之后,為了進(jìn)一步提高分析的準(zhǔn)確率,根據(jù)各個(gè)詞干出現(xiàn)的次數(shù)對(duì)所有的詞干項(xiàng)進(jìn)行排序,研究主要選取出現(xiàn)次數(shù)較高的詞干,而出現(xiàn)次數(shù)較低的詞干不具有代表意義.因此本文將出現(xiàn)次數(shù)小于 10 次的詞干丟棄,不作分析.
缺陷報(bào)告的聚類分析主要是對(duì)數(shù)據(jù)集通過LDA主題模型分析[13-15],然后將不同的缺陷報(bào)告分組到不同的主題中去,以此完成缺陷報(bào)告聚類分析.在 LDA 中,主題的數(shù)量 K 的選擇是非常重要的,K值的大小決定了LDA主題模型提取主題的情況,對(duì)最終主題提取結(jié)果具有一定的影響.因此,通過分析文獻(xiàn)[16]的方法,采用等梯度漸進(jìn)搜索的方式,通過梯度漸進(jìn)搜索獲得K的最優(yōu)值.
算法 1.等梯度LDA搜索最佳主題
輸入:主題數(shù)量的搜索范圍[Mintopic,Maxtopic];
梯度數(shù)組g;
缺陷報(bào)告數(shù)據(jù)集M
輸出:最佳主題數(shù)量kbest、主題topic
算法描述:
1.初始趟數(shù)i=0,根據(jù)i的取值從g中選擇對(duì)應(yīng)梯度gi,按gi從搜索范圍[Mintopic,Maxtopic]內(nèi)選擇一個(gè)等差數(shù)列k,等差數(shù)列的值為主題數(shù)量;
2.將M以及k中的每一項(xiàng)ki作為主題數(shù)量傳入到LDA模型中進(jìn)行訓(xùn)練,計(jì)算Ccoh,并選取Ccoh最高的主題數(shù)ktop;
3.以ktop為中心、gi為半徑,形成新的搜索范圍[min(Mintopic,ky-gi),max(Maxtopic,ky+gi)],搜索的趟數(shù)加1;
4.重復(fù)步驟1-3,直到g遍歷完;
5.輸出Ccoh最高的主題數(shù)即為最佳主題數(shù)kbest;
6.將M以及最佳主題的數(shù)kbest傳入LDA模型中進(jìn)行訓(xùn)練;
7.輸出主題topic;
算法1給出了利用LDA搜索最佳主題數(shù)量并的到最佳主題的過程.將搜索范圍設(shè)為[1,10]的整數(shù),即設(shè)置最佳主題的數(shù)量至少為1個(gè),而至多為10個(gè).此外,g是由一些整數(shù)按照從大到小的順序排列組成.例如以2為梯度進(jìn)行選擇,所選的主題數(shù)數(shù)列為[1,3,5,7,9],通過一致性系數(shù)Ccoh的結(jié)果得到最佳主題數(shù)n為7,結(jié)果如圖3所示.Ccoh計(jì)算使用gensim包中的CoherenceModel實(shí)現(xiàn).Ccoh的大小決定了聚類的效果,對(duì)于后續(xù)的工作有重要的影響.當(dāng)主題數(shù)量對(duì)應(yīng)的一致性系數(shù)較高時(shí),則說明在LDA主題模型中設(shè)置此主題數(shù)量可達(dá)到較好的結(jié)果.通過上述 LDA 的主題數(shù)漸進(jìn)搜索的過程,可以為數(shù)據(jù)集所有缺陷報(bào)告找到適當(dāng)數(shù)量的主題.
圖3 最佳主題數(shù)搜素算法過程中一致性系數(shù)的分布Fig.3 Distribution of coherence coefficient in process of optimal topic number search algorithm
本文通過根據(jù)算法1搜索得到最佳主題,將缺陷報(bào)告分配到對(duì)應(yīng)的主題中.通過對(duì)缺陷報(bào)告的聚類分析,發(fā)現(xiàn)有5類主題中包含了大量的缺陷報(bào)告,共占缺陷報(bào)告總數(shù)的85%.本文決定對(duì)于出現(xiàn)頻率較高的這5類主題進(jìn)行研究.
圖4 各類缺陷所占的比例Fig.4 Proportion of various defects
根據(jù)每一個(gè)主題以及該主題相關(guān)的關(guān)鍵詞,考慮到可讀性和理解效果對(duì)于主題名稱進(jìn)行人工的歸納,本文把5類主題定義為:由數(shù)據(jù)操作造成的軟件缺陷、由控制邏輯造成的軟件缺陷、由計(jì)算過程造成的軟件缺陷、由數(shù)據(jù)庫(kù)造成的軟件缺陷、由調(diào)用過程造成的軟件缺陷,每一個(gè)主題名對(duì)應(yīng)一類缺陷.如圖4所示,給出了聚類分析的結(jié)果——各類缺陷所占比例.
本文對(duì)于上述分析中得到的5類出現(xiàn)頻率較高的缺陷,結(jié)合造成缺陷的原因以及對(duì)于數(shù)據(jù)集中對(duì)應(yīng)的代碼段進(jìn)行分析.首先,分別對(duì)于Stack overflow中5類出現(xiàn)頻率較高的缺陷的數(shù)據(jù),通過人工進(jìn)行隨機(jī)抽樣分析,抽取的比例均為該類缺陷報(bào)告總數(shù)量60%,如表1所示,為用于分析的各類缺陷的數(shù)量.其次,對(duì)于各個(gè)類型下缺陷報(bào)告中的代碼信息進(jìn)行研究,以此列舉出各類缺陷中可能出現(xiàn)的缺陷模式.如表2所示,給出了經(jīng)過分析與研究得到的每一項(xiàng)缺陷類型以及類型的描述以及缺陷情況的列舉.
表1 用于分析的各類缺陷的數(shù)量Table 1 Number of various types of defects used for analysis
表2 缺陷類型以及描述Table 2 Defect type and description
本文需要對(duì)于不同缺陷類別下代碼特征進(jìn)行分析,由于篇幅,這里主要給出出現(xiàn)頻率最高的缺陷—數(shù)據(jù)操作造成的軟件缺陷進(jìn)行研究.通過對(duì)缺陷代碼數(shù)據(jù)集進(jìn)行分析并參考大量相關(guān)文獻(xiàn),針對(duì)數(shù)據(jù)操作缺陷類別下的幾種不同的缺陷代碼情況,通過分析造成此種情況下軟件缺陷的原因,對(duì)影響代碼缺陷的特征進(jìn)行了研究.針對(duì)數(shù)據(jù)操作缺陷的不同缺陷代碼情況分別給出需要關(guān)注的缺陷代碼特征,如表3所示,給出數(shù)據(jù)操作缺陷的幾種情況以及特征和提取方法.
為了進(jìn)行全面的實(shí)驗(yàn)研究,使用在Stack Overflow上名為“Posts.xml”的公開數(shù)據(jù)集.該數(shù)據(jù)集包含從2008年7月-2018年9月的41782536個(gè)帖子.每個(gè)帖子均包括標(biāo)題,正文和相關(guān)信息描述.為了進(jìn)行特征相似度的缺陷檢測(cè)模型,將得到的數(shù)據(jù)按6:4分成兩部分,一部分缺陷報(bào)告的數(shù)據(jù)用于建立缺陷檢測(cè)模型;另一部分缺陷報(bào)告的數(shù)據(jù)用于缺陷檢測(cè)模型的驗(yàn)證.
表3 數(shù)據(jù)操作缺陷不同情況的特征Table 3 Characteristics of different conditions of data manipulation defects
本文主要針對(duì)數(shù)據(jù)操作缺陷構(gòu)建缺陷檢測(cè)模型.數(shù)據(jù)操作缺陷共包含3個(gè)缺陷子類:D1(Java空指針異常)、D2(Java數(shù)據(jù)類型轉(zhuǎn)換異常)、D3(數(shù)組下標(biāo)越界異常);對(duì)于每一缺陷子類都有相應(yīng)的缺陷特征,例如:D1共有4個(gè)缺陷特征分別為聲明類的對(duì)象但未實(shí)例化、聲明類的對(duì)象但指向空值、字符串變量未初始化或初始化為null、接口類型的對(duì)象沒有用具體的類初始化,分別用T11、T12、T13、T14表示,對(duì)應(yīng)的缺陷特征向量分別為D11、D12、D13、D14.本文通過統(tǒng)計(jì)缺陷報(bào)告中各個(gè)缺陷特征出現(xiàn)的頻率設(shè)定每個(gè)缺陷特征的權(quán)重.根據(jù)公式(1)計(jì)算每個(gè)缺陷特征的權(quán)重wkp.
為了評(píng)估本文提出的基于特征相似度的缺陷檢測(cè)模型的有效性,本文從用于驗(yàn)證的40%的缺陷報(bào)告數(shù)據(jù)集中選取了屬于數(shù)據(jù)操作缺陷的缺陷報(bào)告,并把這些缺陷報(bào)告根據(jù)其特征歸到數(shù)據(jù)操作缺陷中的D1、D2、D3共3個(gè)子類.如表4所示,給出了用于驗(yàn)證的數(shù)據(jù)操作缺陷子類的數(shù)量.
本文使用Java開發(fā)語(yǔ)言開發(fā)完成了基于特征相似度的缺陷檢測(cè)模型的開發(fā)程序.檢測(cè)程序在windows平臺(tái)上執(zhí)行,其中內(nèi)存為12GB、CPU為4×3.2GHz、硬盤容量為500GB,該程序?qū)⒈?中的待驗(yàn)證的各類缺陷數(shù)據(jù)作為輸入,使用本文提出的基于特征相似度的缺陷檢測(cè)模型,循壞3次分別檢測(cè)D1、D2、D3情況下相似度的值超過0.60時(shí)的缺陷,輸出檢測(cè)到的缺陷的數(shù)量.其中相似缺陷檢測(cè)算法的執(zhí)行時(shí)間為1908ms,內(nèi)存消耗為40.3MB.最后人工審查檢出缺陷的代碼,計(jì)算準(zhǔn)確率.如表5所示,為相似缺陷檢測(cè)情況統(tǒng)計(jì).
表4 數(shù)據(jù)操作缺陷子類的數(shù)量Table 4 Number of data manipulation defect subclasses
表5 相似缺陷檢測(cè)情況統(tǒng)計(jì)Table 5 Similar defect detection statistics
從表5可以看出,本文提出的基于特征相似度的缺陷檢測(cè)模型可以較準(zhǔn)確地檢測(cè)出不同類相似缺陷,尤其是對(duì)于數(shù)據(jù)操作缺陷子類D1,有較高的準(zhǔn)確率.但是對(duì)于不同的缺陷子類可以檢出缺陷的準(zhǔn)確率不同,存在一定的誤差.本文考慮造成準(zhǔn)確率有高有低的原因和提取得到的缺陷特征關(guān)系較大,缺陷特征提取算法還可以進(jìn)一步完善.
本文基于Stack Overflow中大量數(shù)據(jù)的分析提出了缺陷代碼特征分析的相似缺陷檢測(cè)模型.首先通過聚類分析將Stack Overflow中缺陷報(bào)告分到不同的缺陷類別中,然后對(duì)于數(shù)據(jù)操作缺陷的的幾種情況給出相應(yīng)的缺陷代碼特征以及特征提取的方法,并且對(duì)于每一個(gè)缺陷代碼特征,根據(jù)缺陷代碼數(shù)據(jù)集計(jì)算其權(quán)重,最后,根據(jù)每種缺陷情況下每個(gè)缺陷代碼特征的權(quán)重構(gòu)建特征相似度的缺陷檢測(cè)模型.
實(shí)驗(yàn)結(jié)果表明,本文提出的基于缺陷代碼特征分析的相似缺陷檢測(cè)方法可以檢測(cè)到大部分相似缺陷.本文提出的方法對(duì)于開發(fā)人員在代碼審查和測(cè)試等軟件質(zhì)量保證活動(dòng)中的任務(wù)安排與資源分配有重要作用.但是本文提出的方法在對(duì)于每一種缺陷情況的缺陷代碼特征的提取尚沒能給出自動(dòng)化方法,如果利用機(jī)器學(xué)習(xí)的方法對(duì)于缺陷代碼特征分析并構(gòu)建檢測(cè)模型,對(duì)于診斷新代碼中是否存在相似軟件缺陷更有價(jià)值.