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