亢振興,趙逢禹,劉 亞
(上海理工大學 光電信息與計算機工程學院,上海 200093)
軟件代碼缺陷審查與缺陷預測是研究人員持續關注的問題.代碼缺陷審查主要是通過相關的審查方法,對于源代碼中存在的缺陷進行審查,以此來發現源代碼中可能出現的缺陷情況[1-3].文獻[4]提出了一種高效的檢測源代碼中的安全漏洞的代碼審查方法,對于源代碼中的可操作的內容提取安全特性用于代碼審查.文獻[5]提出了對不同層次代碼對象進行失效模式分析來代替使用傳統檢查單的代碼審查方法.此外,在軟件缺陷預測領域,研究人員利用深度學習挖掘軟件源碼中復雜的非線性特征進行缺陷預測,提出了許多缺陷預測模型[6,7].
在基于代碼的缺陷審查與缺陷預測研究中,研究人員利用專業知識對源代碼進行分析,通過對代碼中特征的綜合評判,以發現代碼中存在的缺陷或有缺陷傾向的代碼段[8].而實際上,在現有的軟件缺陷跟蹤系統中,已經積累了大量的歷史缺陷代碼信息[9,10],相同的缺陷在不同的軟件項目也會重復出現,對這些缺陷代碼信息的分析與研究對于發現軟件中類似缺陷具有重要參考價值.例如:Stack Overflow是一個計算機領域較為流行的交流社區,人們可以在上面發帖提出問題或者回答他人的提問,經過長時間的發展,此交流社區中也積累了大量有關于代碼缺陷的問答貼[10,11],這些帖子也稱為缺陷報告,在Stack Overflow中大量的缺陷報告形成了龐大的數據集.缺陷報告除了文本外,還有大量的編程代碼,這些代碼是使用者在進行提問時提交的問題代碼.因此,在Stack Overflow中包含了許多有關于缺陷代碼的信息.如何通過對于已發現缺陷代碼的特征研究,構建特征提取方法,利用這些缺陷代碼特征,分析與檢測其他源代碼中存在的缺陷傾向,對于發現的疑似缺陷提前進行檢測和處理,對開發人員在代碼審查和測試等軟件質量保證活動中的任務安排與資源分配有重要指導意義.
基于缺陷代碼特征相似缺陷檢測的核心是對缺陷代碼的特征提取.
本文首先對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的特征的相似度,相似度越大則該代碼段含有此類缺陷的可疑度就越大.最后,將缺陷可疑度較高的代碼段可優先進行人工審查,確定是否為缺陷代碼.
在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
在缺陷報告中,缺陷報告的標題、缺陷的描述等文本信息和缺陷情況密切相關,也更加準確地反映不同缺陷之間的聯系.因此,為了高效快速地對缺陷報告進行分類,對于每一個缺陷報告的標簽、標題和正文的文本信息分別進行研究與探分析.本文的研究中,首先提取與本文研究內容相符合的標簽;其次根據標簽對與本文研究內容相關的缺陷報告進行篩選并對問題的文本信息進行提取;最后根據文本信息提取主題并將數據集中的缺陷報告分別分配到相應的主題中,以此結果作為缺陷報告聚類的結果.
本文主要針對Java代碼中缺陷的情況進行分析,因此,Tags中含有“Java”作為首要的查找條件.首先遍歷數據集找到標簽中含有“Java”的缺陷報告,此缺陷報告可列入本文初始數據集;其次如果Tags中不含有“Java”時,遍歷數據集中缺陷報告的標題(Title)和描述(Body),若其中含有“Java”,則此缺陷報告可列入本文初始數據集;最后丟棄除此之外的不相關的缺陷報告.
每一個缺陷報告包括標題、正文和其他描述信息.為了將缺陷報告聚類,需要提取缺陷描述的文本信息.缺陷描述的文本信息提取的步驟如下:
1)刪除缺陷報告中含有標簽的部分,提取缺陷報告中剩余的部分;
標簽)部分、停用詞、數字、標點符號和其他非字母字符等部分,提取缺陷報告中剩余的部分;
3)使用 Snowball詞干分析器提取詞匯的詞干部分(例如,“effective”和“effects”提取的詞干為“effect”),通過這個方法可以提取到詞匯的詞干部分,將相似的詞匯統一為相同的形式.
在上述 3 個步驟之后,為了進一步提高分析的準確率,根據各個詞干出現的次數對所有的詞干項進行排序,研究主要選取出現次數較高的詞干,而出現次數較低的詞干不具有代表意義.因此本文將出現次數小于 10 次的詞干丟棄,不作分析.
缺陷報告的聚類分析主要是對數據集通過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所示,給出了聚類分析的結果——各類缺陷所占比例.
本文對于上述分析中得到的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
本文需要對于不同缺陷類別下代碼特征進行分析,由于篇幅,這里主要給出出現頻率最高的缺陷—數據操作造成的軟件缺陷進行研究.通過對缺陷代碼數據集進行分析并參考大量相關文獻,針對數據操作缺陷類別下的幾種不同的缺陷代碼情況,通過分析造成此種情況下軟件缺陷的原因,對影響代碼缺陷的特征進行了研究.針對數據操作缺陷的不同缺陷代碼情況分別給出需要關注的缺陷代碼特征,如表3所示,給出數據操作缺陷的幾種情況以及特征和提取方法.
為了進行全面的實驗研究,使用在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,有較高的準確率.但是對于不同的缺陷子類可以檢出缺陷的準確率不同,存在一定的誤差.本文考慮造成準確率有高有低的原因和提取得到的缺陷特征關系較大,缺陷特征提取算法還可以進一步完善.
本文基于Stack Overflow中大量數據的分析提出了缺陷代碼特征分析的相似缺陷檢測模型.首先通過聚類分析將Stack Overflow中缺陷報告分到不同的缺陷類別中,然后對于數據操作缺陷的的幾種情況給出相應的缺陷代碼特征以及特征提取的方法,并且對于每一個缺陷代碼特征,根據缺陷代碼數據集計算其權重,最后,根據每種缺陷情況下每個缺陷代碼特征的權重構建特征相似度的缺陷檢測模型.
實驗結果表明,本文提出的基于缺陷代碼特征分析的相似缺陷檢測方法可以檢測到大部分相似缺陷.本文提出的方法對于開發人員在代碼審查和測試等軟件質量保證活動中的任務安排與資源分配有重要作用.但是本文提出的方法在對于每一種缺陷情況的缺陷代碼特征的提取尚沒能給出自動化方法,如果利用機器學習的方法對于缺陷代碼特征分析并構建檢測模型,對于診斷新代碼中是否存在相似軟件缺陷更有價值.