基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法
【專利摘要】一種基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,根據(jù)多線程程序語義構(gòu)建約束表達(dá)式,將數(shù)據(jù)競爭檢測問題轉(zhuǎn)化為約束求解問題,采用約束求解器檢測可能存在的數(shù)據(jù)競爭,并生成觸發(fā)數(shù)據(jù)競爭的程序執(zhí)行路徑,首先插樁被檢測程序,執(zhí)行此程序并得到執(zhí)行路徑;其次根據(jù)多線程程序執(zhí)行語義將執(zhí)行路徑轉(zhuǎn)化為無量詞一階邏輯表達(dá)式,此約束表達(dá)式涵蓋所有可行的線程交織;然后根據(jù)發(fā)生數(shù)據(jù)競爭時語句間時序關(guān)系構(gòu)建數(shù)據(jù)競爭候選集合,生成候選發(fā)生競爭的條件;最后遍歷候選集合判定是否存在數(shù)據(jù)競爭,如有則生成對應(yīng)的證據(jù)序列,本方法可找出一次執(zhí)行中所有的數(shù)據(jù)競爭且不存在誤報情況,對每一個數(shù)據(jù)競爭都生成一個展示了數(shù)據(jù)競爭觸發(fā)過程的證據(jù)序列。
【專利說明】基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及可信軟件及軟件測試領(lǐng)域,特別涉及一種基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法。
【背景技術(shù)】
[0002]隨著處理器多核化的普及,多線程技術(shù)已經(jīng)成為軟件編程中提高CPU利用率不可或缺的技術(shù)。然而,由于線程之間交織的不確定性,多線程程序執(zhí)行過程中可能會出現(xiàn)一些難以預(yù)料的行為導(dǎo)致程序出錯,例如對臨界區(qū)沒有做好同步工作而導(dǎo)致的數(shù)據(jù)競爭問題。數(shù)據(jù)競爭是兩個不同的線程在沒有同步保護(hù)的情況同時訪問一個內(nèi)存,并且至少有一個寫操作。數(shù)據(jù)競爭不一定導(dǎo)致程序錯誤,因為有些程序員故意讓程序有數(shù)據(jù)競爭以提高運行的效率,但是有調(diào)查表明5-24%的數(shù)據(jù)競爭會對程序產(chǎn)生壞影響。數(shù)據(jù)競爭很難以被發(fā)現(xiàn),因為它們經(jīng)常發(fā)生在一些低概率出現(xiàn)的交織序列中,在現(xiàn)實中往往需要花很多時間去定位,其引起的錯誤如同“corner error”,即使在軟件發(fā)布時也未必能夠完全清除它們。因此,數(shù)據(jù)競爭檢測是多線程程序測試領(lǐng)域最受關(guān)注的研究點之一。
[0003]過去幾十年中數(shù)據(jù)競爭檢測已有大量研究,設(shè)計出很多杰出的自動化檢測工具,主要分為靜態(tài)與動態(tài)分析技術(shù)。靜態(tài)方法通過靜態(tài)檢測程序所有的路徑來推斷程序中的所有數(shù)據(jù)競爭,可以檢測出大部分?jǐn)?shù)據(jù)競爭;但由于使用大量假設(shè),靜態(tài)分析方法會產(chǎn)生無效的數(shù)據(jù)競爭,導(dǎo)致誤報率較高。動態(tài)方法通過監(jiān)控一次執(zhí)行中內(nèi)存與同步信息以確定是否存在數(shù)據(jù)競爭,能夠提供較高精度的檢測結(jié)果;但是動態(tài)分析方法受到交織與路徑的影響,往往要通過多次執(zhí)行來提高覆蓋率。本文將靜態(tài)代碼分析與程序執(zhí)行過程監(jiān)測相結(jié)合,以提高覆蓋率且盡可能消除誤報。
[0004]現(xiàn)有的動態(tài)檢測技術(shù)主要分為三種:基于lockset、基于happens-before與二者結(jié)合的方法。I)基于1ckset的方法對線程交織不敏感,但是存在誤報情況,即無效競爭。
2)基于happens-before的方法只檢測某特定交織序列上的數(shù)據(jù)競爭,檢測結(jié)果雖可靠,但敏感于線程交織。3)混合方法結(jié)合了兩者的優(yōu)點,并且試圖減小各自的缺點,但也面臨如不能夠搜索出隱藏的錯誤、1ckset高誤報引起的無效報警等問題。
【發(fā)明內(nèi)容】
[0005]為了克服上述現(xiàn)有技術(shù)的缺點,本發(fā)明的目的在于提供一種基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,根據(jù)多線程程序語義構(gòu)建約束表達(dá)式,將數(shù)據(jù)競爭檢測問題轉(zhuǎn)化為約束求解問題,采用約束求解器檢測可能存在的數(shù)據(jù)競爭,并生成觸發(fā)數(shù)據(jù)競爭的程序執(zhí)行路徑。
[0006]為了實現(xiàn)上述目的,本發(fā)明采用的技術(shù)方案是:
[0007]—種基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,包括如下步驟:
[0008]SI)在給定輸入下,通過執(zhí)行已插樁的待測程序以生成路徑記錄文件,且識別出執(zhí)行路徑中公有變量的訪問點以便于約束構(gòu)建;
[0009]S2)根據(jù)程序執(zhí)行語義將執(zhí)行路徑中狀態(tài)轉(zhuǎn)移、線程交織關(guān)系轉(zhuǎn)化為無量詞一階邏輯表達(dá)式,構(gòu)建蘊含了所有可能的交織序列的多線程程序執(zhí)行路徑約束模型F ;
[0010]S3)將路徑中所有線程上可能發(fā)生數(shù)據(jù)競爭的兩點視為數(shù)據(jù)競爭候選,收集所有候選并構(gòu)建數(shù)據(jù)競爭候選集合DRCS,同時根據(jù)數(shù)據(jù)競爭的定義構(gòu)建每個候選的競爭發(fā)生條件P ;
[0011]S4)針對每一個候選競爭發(fā)生條件P,利用約束求解器驗證FAp是否有解;
[0012]S5)如果有解,則表示此競爭條件會觸發(fā)真實的數(shù)據(jù)競爭;如果無解,則表示此候選不會觸發(fā)數(shù)據(jù)競爭;
[0013]S6)當(dāng)存在數(shù)據(jù)競爭時,輸出該數(shù)據(jù)競爭的證據(jù)序列;
[0014]S7)對于數(shù)據(jù)競爭候選集合DRCS,如果遍歷結(jié)束,則輸出所有結(jié)果;否則,繼續(xù)遍歷下一個競爭候選;
[0015]S8)驗證結(jié)束后,輸出檢測到的所有數(shù)據(jù)競爭以及對應(yīng)的證據(jù)序列。
[0016]本發(fā)明進(jìn)一步的改進(jìn)在于:所述步驟SI)中插樁工作并非在源碼或者二進(jìn)制的層面上進(jìn)行,而是在字節(jié)碼的層面上完成,具體實施方法為:首先將待測多線程程序源碼轉(zhuǎn)化為中間字節(jié)碼格式,即LLVM字節(jié)碼;然后將具有監(jiān)控功能的語句植入待測程序;最后將植入監(jiān)控代碼的字節(jié)碼鏈接成可執(zhí)行程序。
[0017]本發(fā)明進(jìn)一步的改進(jìn)在于:所述步驟S2)中多線程程序執(zhí)行路徑約束模型F蘊含了執(zhí)行路徑所有可能的交織序列,包括五種約束:路徑表達(dá)式、內(nèi)存模型約束、讀寫關(guān)系約束、偏序約束以及同步語義約束,定義分別如下:
[0018]I)路徑表達(dá)式:描述線程內(nèi)部的定義-使用鏈,以及控制線程內(nèi)部狀態(tài)轉(zhuǎn)換;
[0019]2)內(nèi)存模型約束:表示程序中語句、變量之間的關(guān)系,采用順序一致性的語義,順序一致性規(guī)定CPU按照代碼中語句的順序來執(zhí)行程序;
[0020]3)讀寫關(guān)系約束:定義線程間的定義-使用鏈,規(guī)定共享變量所讀取到的值,必須來自初始值以及最近的寫值;
[0021]4)偏序約束:定義線程之間創(chuàng)建線程與終止線程操作語句于被操作線程語句之間的時序關(guān)系;
[0022]5)同步語義約束:定義線程之間同步控制操作語句之間的時序關(guān)系;
[0023]其中,定義-使用鏈為:將每一個線程序列轉(zhuǎn)化為SSA格式,對于每一個SSA格式的執(zhí)行序列,除去共享訪問點都是一個完整的定義-使用鏈。
[0024]本發(fā)明進(jìn)一步的改進(jìn)在于:所述步驟S2)中多線程程序執(zhí)行路徑約束模型F的構(gòu)建方法包括以下操作:
[0025]I)計算路徑表達(dá)式,以控制線程內(nèi)部狀態(tài)轉(zhuǎn)移;
[0026]2)計算內(nèi)存模型約束,以線程內(nèi)限制語句之間的關(guān)系;
[0027]3)計算讀寫關(guān)系約束,以建立線程間的定義-使用鏈;
[0028]4)計算同步語義約束,以定義線程間同步關(guān)系;
[0029]5)計算偏序約束,以描述線程創(chuàng)建與終止的語義;
[0030]最后,結(jié)合以上五種約束,構(gòu)成約束模型F。
[0031]本發(fā)明進(jìn)一步的改進(jìn)在于:定義執(zhí)行路徑事件集-"「I = {?\0 < i < Μ,其中k
為線程數(shù)量,Ti = Ie1, e2,…,en}作為線程i的執(zhí)行序列,en表示Ti的第η個事件,0(en)表示事件en的順序,η表示Ti的事件數(shù)量,則:
[0032]所述路徑表達(dá)式的計算方法:
[0033]將每一個線程序列轉(zhuǎn)化為SSA格式,類似于路徑條件(Path Condit1n)的收集,直接將SSA格式序列轉(zhuǎn)化為路徑表達(dá)式;
[0034]所述內(nèi)存模型約束的計算方法:
[0035]采用順序一致性模型,所有操作完全按程序的順序執(zhí)行,線程內(nèi)的事件順序符合約束:
[0036]
【權(quán)利要求】
1.一種基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,包括如下步驟: 51)在給定輸入下,通過執(zhí)行已插樁的待測程序以生成路徑記錄文件,且識別出執(zhí)行路徑中公有變量的訪問點以便于約束構(gòu)建; 52)根據(jù)程序執(zhí)行語義將執(zhí)行路徑中狀態(tài)轉(zhuǎn)移、線程交織關(guān)系轉(zhuǎn)化為無量詞一階邏輯表達(dá)式,構(gòu)建蘊含了所有可能的交織序列的多線程程序執(zhí)行路徑約束模型F ; 53)將路徑中所有線程上可能發(fā)生數(shù)據(jù)競爭的兩點視為數(shù)據(jù)競爭候選,收集所有候選并構(gòu)建數(shù)據(jù)競爭候選集合DRCS,同時根據(jù)數(shù)據(jù)競爭的定義構(gòu)建每個候選的競爭發(fā)生條件P ; 54)針對每一個候選競爭發(fā)生條件P,利用約束求解器驗證FΛ P是否有解; 55)如果有解,則表示此競爭條件會觸發(fā)真實的數(shù)據(jù)競爭;如果無解,則表示此候選不會觸發(fā)數(shù)據(jù)競爭; 56)當(dāng)存在數(shù)據(jù)競爭時,輸出該數(shù)據(jù)競爭的證據(jù)序列; 57)對于數(shù)據(jù)競爭候選集合DRCS,如果遍歷結(jié)束,則輸出所有結(jié)果;否則,繼續(xù)遍歷下一個競爭候選; 58)驗證結(jié)束后,輸出檢測到的所有數(shù)據(jù)競爭以及對應(yīng)的證據(jù)序列。
2.根據(jù)權(quán)利要求1所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,所述步驟SI)中插樁工作并非在源碼或者二進(jìn)制的層面上進(jìn)行,而是在字節(jié)碼的層面上完成,具體實施方法為:首先將待測多線程程序源碼轉(zhuǎn)化為中間字節(jié)碼格式,即LLVM字節(jié)碼;然后將具有監(jiān)控功能的語句植入待測程序;最后將植入監(jiān)控代碼的字節(jié)碼鏈接成可執(zhí)行程序。
3.根據(jù)權(quán)利要求1所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,所述步驟S2)中多線程程序執(zhí)行路徑約束模型F蘊含了執(zhí)行路徑所有可能的交織序列,包括五種約束:路徑表達(dá)式、內(nèi)存模型約束、讀寫關(guān)系約束、偏序約束以及同步語義約束,定義分別如下: 1)路徑表達(dá)式:描述線程內(nèi)部的定義-使用鏈,以及控制線程內(nèi)部狀態(tài)轉(zhuǎn)換; 2)內(nèi)存模型約束:表示程序中語句、變量之間的關(guān)系,采用順序一致性的語義,順序一致性規(guī)定CPU按照代碼中語句的順序來執(zhí)行程序; 3)讀寫關(guān)系約束:定義線程間的定義-使用鏈,規(guī)定共享變量所讀取到的值,必須來自初始值以及最近的寫值; 4)偏序約束:定義線程之間創(chuàng)建線程與終止線程操作語句于被操作線程語句之間的時序關(guān)系; 5)同步語義約束:定義線程之間同步控制操作語句之間的時序關(guān)系; 其中,定義-使用鏈為:將每一個線程序列轉(zhuǎn)化為SSA格式,對于每一個SSA格式的執(zhí)行序列,除去共享訪問點都是一個完整的定義-使用鏈。
4.根據(jù)權(quán)利要求3所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,所述步驟S2)中多線程程序執(zhí)行路徑約束模型F的構(gòu)建方法包括以下操作: 1)計算路徑表達(dá)式,以控制線程內(nèi)部狀態(tài)轉(zhuǎn)移; 2)計算內(nèi)存模型約束,以線程內(nèi)限制語句之間的關(guān)系;3)計算讀寫關(guān)系約束,以建立線程間的定義-使用鏈; 4)計算同步語義約束,以定義線程間同步關(guān)系; 5)計算偏序約束,以描述線程創(chuàng)建與終止的語義; 最后,結(jié)合以上五種約束,構(gòu)成約束模型F。
5.根據(jù)權(quán)利要求4所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,定義執(zhí)行路徑事件集合Επ = |Τ(_|0 < ? < /ch其中k為線程數(shù)量,Ti = Ie1,e2,…,en}作為線程i的執(zhí)行序列,en表示Ti的第η個事件,0(en)表示事件en的順序,η表示Ti的事件數(shù)量,則: 所述路徑表達(dá)式的計算方法: 將每一個線程序列轉(zhuǎn)化為SSA格式,直接將SSA格式序列轉(zhuǎn)化為路徑表達(dá)式; 所述內(nèi)存模型約束的計算方法: 采用順序一致性模型,所有操作完全按程序的順序執(zhí)行,線程內(nèi)的事件順序符合約束:
其中61與^+1表示同一線程內(nèi)連續(xù)的兩個事件,τ表示所有線程序列; 所述讀寫關(guān)系約束的計算方法: 使共享變量的讀來自于最近的寫,對于同一共享變量V,令R作為所有對其進(jìn)行讀操作的事件集合,令W作為所有對其進(jìn)行寫操作的事件集合,給出以下公式:
其中,er為讀事件,ew與ex為寫事件,Vr和Vw為事件^與ew所操作的變量,公式所表達(dá)的意思是,如果事件^中的 ' 取值來自于事件ew中的vw,首先要滿足^在ew之后,即0(ew) <0(er);然后要滿足所有的寫要么在ew之前,要么在&之后; 所述同步語義約束的計算方法包括lock/unlock與wait/signal兩類操作: 1)lock/unlock操作的目的為構(gòu)建鎖同步語義約束,要求在同一互斥鎖的lock/unlock集合L中,對于任意兩個lock/unlock事件對=IiAii與lk/uk,須滿足公式:
其中,鎖對IiAii要么發(fā)生在鎖對lk/uk之前,要么發(fā)生在其后; 2)wait/signal操作的目的是構(gòu)建條件變量同步語義約束,要滿足條件:每一個wait操作必須對應(yīng)一個signal操作,而一個signal操作至多喚醒一個wait操作,對于同一條件變量cond,令WT作為在cond上所有wait操作的集合,令SG作為在cond上所有signal操作的集合,如要滿足之上的條件,須有以下公式:
其中,ewt為WT中的任一元素,SGwt表示ewt可以匹配的signal操作的集合,esg為SGlrt中任一 signal操作事件,利用變量pair#是否等于I來表示esg是否與ewt相匹配。子公式IeeSGwiPaiT^t = I表示,對于每一個wait操作ewt必須有一個signal操作與之匹配; 所述偏序約束的計算方法: 首先規(guī)定:如果事件創(chuàng)建一個線程,那么被創(chuàng)建線程的所有事件都要在此事件之后執(zhí)行;如果事件執(zhí)行線程終止操作,那么被終止線程的所有事件都要在此事件之前;令C為create/fork操作的事件集合,令J作為join操作的事件集合;給定約束:
其中,e。為線程創(chuàng)建事件,first (e。)為e。所創(chuàng)建的線程首個事件的順序;&為線程終止事件;last(ep為&所結(jié)束的線程末尾事件的順序; 最終將以上五種約束相與構(gòu)成約束模型F。
6.根據(jù)權(quán)利要求1所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,所述步驟S3)中競爭發(fā)生條件P的構(gòu)建方法如下:如果有一條路徑τ =〈Tiei^ τ2>,其中^是前綴,τ2是后綴,事件&與&屬于不同的線程并且都訪問同一內(nèi)存,至少有一個寫,那么二者之間發(fā)生了數(shù)據(jù)競爭,而τ看作是^與&數(shù)據(jù)競爭的證據(jù)序列;對于訪問同一變量的事件ei與ek, e' i與e" i分別表不Oi的前一個事件與后一個事件;同樣,e' k與e" k分別表示ek的前一個事件與后一個事件,那么兩者發(fā)生數(shù)據(jù)競爭即同時訪問同一內(nèi)存的條件P為:
0(e' J < 0(ek) < 0(e" J Λ 0(e' k) < (Kei) < 0(e" k)。
7.根據(jù)權(quán)利要求1所述基于多線程程序約束構(gòu)建的數(shù)據(jù)競爭檢測與證據(jù)生成方法,其特征在于,所述步驟S7)中對于每一個數(shù)據(jù)競爭都會生成證據(jù)序列,以描述其觸發(fā)過程。
【文檔編號】G06F9/44GK104077144SQ201410320943
【公開日】2014年10月1日 申請日期:2014年7月7日 優(yōu)先權(quán)日:2014年7月7日
【發(fā)明者】劉烴, 張曉東, 俞樂晨, 劉沛, 鄭慶華 申請人:西安交通大學(xué)