本發(fā)明涉及軟件測試技術(shù)領(lǐng)域,具體涉及一種基于約束求解的原子違背探測方法。
背景技術(shù):
隨著多核處理器的普及,并發(fā)編程技術(shù)得到了廣泛的應(yīng)用。由于并發(fā)程序的執(zhí)行交織空間大、運(yùn)行不確定,并發(fā)程序錯(cuò)誤的測試、調(diào)試以及修復(fù)十分困難。其中,原子違背是其中最常見的并發(fā)錯(cuò)誤,約占非死鎖類型并發(fā)錯(cuò)誤的65%?,F(xiàn)有的原子違背探測技術(shù)大致分為三類:靜態(tài)探測技術(shù)、運(yùn)行時(shí)監(jiān)測技術(shù)和運(yùn)行時(shí)預(yù)測技術(shù)。其中,靜態(tài)探測技術(shù)可在程序源代碼級(jí)別識(shí)別出潛在的原子違背錯(cuò)誤,但其無法處理鎖以外的其他類型的同步原語,誤檢率高。運(yùn)行時(shí)監(jiān)測技術(shù)監(jiān)測并發(fā)程序執(zhí)行,探測在程序?qū)嶋H執(zhí)行中暴露出的原子違背錯(cuò)誤,其誤檢率低,但漏檢率高。運(yùn)行時(shí)預(yù)測技術(shù)通過對程序執(zhí)行序列進(jìn)行分析和處理,可探測出隱藏在程序執(zhí)行序列中尚未暴露的原子違背。然而,現(xiàn)有很多運(yùn)行時(shí)預(yù)測技術(shù)或者由于采用了保守的并發(fā)程序模型,其探測結(jié)果具有較高的誤檢率,或者由于搜索交織空間有限,具有較高的漏檢率。
若某執(zhí)行軌跡至少滿足Happened-Before和鎖保護(hù)兩個(gè)約束,則稱其為合法軌跡。其中,Happened-Before關(guān)系約束,包含以下三個(gè)方面:
●若事件ei,ej屬于同一線程,且ei發(fā)生在ej之前,那么在任何情況下ei都在ej之前執(zhí)行;
●若事件ei開啟了ej所在的線程,那么ei必須在ej前發(fā)生;
●若事件ej等待來在ei發(fā)送的信息,那么ei在ej前發(fā)生;
鎖約束(Lock Constraint):每一個(gè)鎖對(acquire-release)都不能與其他操作同一鎖變量的鎖對產(chǎn)生交織,即在任何情況下對于任何一個(gè)鎖只能被一個(gè)線程擁有,以保證互斥訪問。
對同一共享變量進(jìn)行訪問的原子違背有如下五種模式,如表1,其中ti表示線程,Ri,Wj分別表示線程ti的讀事件與寫事件,m表示事件所存取的內(nèi)存位置。
表1:原子違背的各種模式
技術(shù)實(shí)現(xiàn)要素:
針對現(xiàn)有技術(shù)的不足,本發(fā)明提出一種基于約束求解的原子違背探測方法,將原子違背的探測問題轉(zhuǎn)化為約束等式的求解問題,可有效降低原子違背探測的誤檢率,提高其探測能力。
為實(shí)現(xiàn)上述方面目的,本發(fā)明采用如下技術(shù)方案:
一種基于約束求解的原子違背探測方法,利用并發(fā)程序原始執(zhí)行軌跡,結(jié)合原子違背的各種錯(cuò)誤模式,建立原始執(zhí)行軌跡中事件之間執(zhí)行先后順序的約束關(guān)系,并求解,當(dāng)約束有解時(shí),該解對應(yīng)的新的執(zhí)行軌跡中存在原子違背現(xiàn)象,當(dāng)約束無解時(shí),則不存在原子違背現(xiàn)象。
進(jìn)一步的,包括以下步驟:
步驟1):記錄原始執(zhí)行軌跡:
步驟11):對原始程序進(jìn)行插樁,以便在運(yùn)行時(shí)記錄需要的執(zhí)行軌跡信息;
步驟12):執(zhí)行原始程序,記錄執(zhí)行軌跡,一個(gè)執(zhí)行軌跡是一個(gè)事件序列,表示為δ=<e1,e2,…ei,…,en>,其中每個(gè)事件ei包含下列屬性:
ti:事件ei所屬的線程;
mi:事件ei所存取的內(nèi)存位置;
li:當(dāng)事件ei執(zhí)行時(shí),其所擁有的鎖;
ai:事件ei的存取類型,包括讀、寫、獲取鎖、釋放鎖、等待、通知、創(chuàng)建線程和等待線程結(jié)束等八種類型;
步驟2):由步驟1)所得的原始執(zhí)行軌跡和預(yù)定義的原子區(qū)域模式確定原子性區(qū)域,并利用原子區(qū)域和原子違背的各種錯(cuò)誤模式收集潛在的可能會(huì)引起不可序列化交織的事件序列:
步驟21):由步驟1)所得的執(zhí)行軌跡和預(yù)定義的原子區(qū)域模式,確定原子性區(qū)域;將每個(gè)synchronized方法,synchronized代碼塊以及鎖保護(hù)的代碼塊均視為原子區(qū)域;
步驟22):給定a,b,c三個(gè)事件,其中thread(a)=thread(b)≠thread(c),若事件a,b屬于步驟21)所得的同一原子性區(qū)域,且這三個(gè)事件的讀寫類型符合某個(gè)原子違背模式中對應(yīng)的事件讀寫類型,則事件a,b,c是一個(gè)潛在的可能會(huì)引起不可序列化交織的事件序列;收集這些潛在的可能會(huì)引起不可序列化交織的事件序列,對這些收集的事件序列,進(jìn)一步探測是否存在執(zhí)行軌跡使這些事件序列中的三個(gè)事件的執(zhí)行順序符合不可序列化交織模式;
步驟3):建立原子違背約束;
對步驟22)中得到的事件序列建立原子違背約束,其中(a,c,b)是某個(gè)事件序列中的三個(gè)事件,其中thread(a)=thread(b)≠thread(c),且事件a,b來自同一原子性區(qū)域,約束內(nèi)容分為兩部分:
第一部分:在求解出的執(zhí)行軌跡中事件c要在事件a和事件b之間被執(zhí)行;
第二部分:事件a,b,c在求解出的執(zhí)行軌跡中一定會(huì)被執(zhí)行,但不要求事件a,b,c讀寫的值與原執(zhí)行軌跡中的事件a,b,c讀寫的值一樣;
步驟4):原子違背約束求解
使用Z3約束求解器進(jìn)行約束求解,當(dāng)約束有解時(shí),該解對應(yīng)的新的執(zhí)行軌跡中存在原子違背現(xiàn)象,否則不存在。
本發(fā)明的有益效果為:1、對原始程序軌跡和每個(gè)不可序列化的執(zhí)行交織建立一組約束,將探測原子違背問題轉(zhuǎn)化為約束的求解問題,提高原子違背探測的精度;
2、本方法屬于運(yùn)行時(shí)預(yù)測技術(shù),可根據(jù)約束求解出隱藏在原始執(zhí)行軌跡中沒有暴露出的原子違背錯(cuò)誤,具有更好的探測原子違背的能力。
附圖說明
圖1為本發(fā)明方法的實(shí)施流程圖。
具體實(shí)施方式
本發(fā)明利用并發(fā)程序原始執(zhí)行軌跡,結(jié)合原子違背的各種錯(cuò)誤模式,建立原始執(zhí)行軌跡中事件之間執(zhí)行先后順序的約束關(guān)系,并求解,當(dāng)約束有解時(shí),該解對應(yīng)的新的執(zhí)行軌跡中存在原子違背現(xiàn)象,否則不存在,具體而言,包括以下步驟:
1.得到執(zhí)行軌跡:
(1)對原始程序進(jìn)行插樁,以便在運(yùn)行時(shí)記錄需要的軌跡執(zhí)行信息;
順序掃描被測程序中的每條語句,在特定的語句前后插樁代碼,如:同步語句、賦值語句、分支語句等,在實(shí)際執(zhí)行時(shí)收集與這些語句相關(guān)的信息以組合成事件并保存到數(shù)據(jù)庫中;
(2)執(zhí)行插樁后的原始并發(fā)程序,得到執(zhí)行軌跡,一個(gè)執(zhí)行軌跡是一個(gè)事件序列,表示為δ=<e1,e2,…ei,…,en>,其中每個(gè)事件ei包含下列屬性:
ti:事件ei所屬的線程;
mi:事件ei所存取的內(nèi)存位置;
li:當(dāng)事件ei執(zhí)行時(shí),其所擁有的鎖;
ai:事件ei的存取類型,包括讀,寫,獲取鎖,釋放鎖,等待,通知,創(chuàng)建線程和等待線程結(jié)束8種類型。
2.利用所得執(zhí)行軌跡和預(yù)定義的原子區(qū)域模式確定原子性區(qū)域,并利用原子區(qū)域和原子違背的各種錯(cuò)誤模式收集潛在的可能會(huì)引起不可序列化交織的事件序列:
(1)本發(fā)明中將每個(gè)synchronized方法,synchronized代碼塊以及鎖保護(hù)的代碼塊均看做原子區(qū)域;
執(zhí)行軌跡中包含進(jìn)入和退出synchronized方法,synchronized代碼塊和鎖保護(hù)區(qū)域的acquire和release事件,通過分析執(zhí)行軌跡得到每個(gè)線程訪問每個(gè)鎖變量的<acquire,release>對序列,對于每個(gè)<acquire,release>事件對,定位acquire和release事件在對應(yīng)線程執(zhí)行軌跡中的位置,并將acquire和release事件的位置作為原子區(qū)域邊界;將每對原子區(qū)域邊界之間的事件序列看作一個(gè)原子區(qū)域;
(2)a,b,c三個(gè)事件,其中thread(a)=thread(b)≠thread(c),事件a,b屬于步驟21)所得的同一原子性區(qū)域,且這三個(gè)事件的讀寫類型符合某個(gè)原子違背模式中對應(yīng)的事件讀寫類型,則事件a,b,c是一個(gè)潛在的可能會(huì)引起不可序列化交織的事件序列,收集這些潛在的可能會(huì)引起不可序列化交織的事件序列,對收集的這些事件序列,我們進(jìn)行進(jìn)一步探測是否存在執(zhí)行軌跡能使得這些事件序列中的三個(gè)事件的執(zhí)行順序符合不可序列化交織模式;
對每組由三個(gè)事件a,b,c組成的可能會(huì)引起不可序列化交織的事件序列進(jìn)行快速檢查,判斷此事件序列是否滿足構(gòu)成原子違背的前提條件,快速檢查的內(nèi)容包括:檢查事件c和事件a,b是否被同一把鎖保護(hù),事件c和事件a,b之間是否存在happened-before關(guān)系;若滿足這兩個(gè)條件的任意一條則表明事件c不會(huì)發(fā)生在事件a和b之間,即不會(huì)構(gòu)成一個(gè)真正的原子違背,因此不需要對此事件序列建立約束。
3.約束的建立與求解,驗(yàn)證步驟2得到的潛在的可能會(huì)引起不可序列化交織的事件序列是否是真正的原子違背;
為驗(yàn)證步驟2得到的潛在的可能會(huì)引起不可序列化交織的事件序列是否是真正的原子違背,需求解是否存在執(zhí)行軌跡能使所得事件序列中的三個(gè)事件的執(zhí)行順序符合不可序列化交織模式,對步驟1)中得到的執(zhí)行軌跡和步驟22)中得到的事件序列建立約束并求解,需要建立的約束等式有:happened-before約束、鎖互斥約束、原子違背約束,將原子違背的探測問題轉(zhuǎn)化為約束等式的求解問題。
(1)建立原子違背約束:
對步驟2中得到的事件序列建立原子違背約束,其中(a,c,b)是某個(gè)事件序列中的三個(gè)事件,其中thread(a)=thread(b)≠thread(c),且事件a,b來自同一原子性區(qū)域,約束內(nèi)容主要分為兩部分:
(11)事件a,b,c執(zhí)行的順序約束,在原子違背模式中要求事件c在事件事件a和事件b之間被執(zhí)行,因此c在事件a和事件b之間被執(zhí)行是此事件序列構(gòu)成原子違背的必要條件,因此在求解出的執(zhí)行軌跡中事件c要在事件a和事件b之間被執(zhí)行;
(12)需要保證事件a,b,c在求解出的執(zhí)行軌跡中一定會(huì)被執(zhí)行,但不要求事件a,b,c讀寫的值與原執(zhí)行軌跡中的事件a,b,c讀寫的值一樣;
由于不要求read和write事件讀寫特定的值,因此影響讀寫事件e的可行性因素除了Happened-before關(guān)系和鎖一致性要求以外,還有一些必須發(fā)生在e之前的分支(branch)事件;若這些branch事件是不可行的,則事件e也是不可行的,即在事件e在求解出的執(zhí)行軌跡中不會(huì)執(zhí)行,因此需要保證這些branch事件的可行性;
對每個(gè)讀寫事件e只需考慮每個(gè)線程距離事件e最近,且和e有偏序關(guān)系的branch事件的具體可行性,“具體”表示某事件在求解出的執(zhí)行軌跡中所有屬性的值都和原執(zhí)行軌跡中對應(yīng)的事件相等;branch事件的可行性依賴于在同一線程內(nèi)在branch事件之前的所有read事件,即約束branch事件所依賴的read事件的值在求解出的執(zhí)行軌跡中與原執(zhí)行軌跡中相等;branch事件的可行性約束進(jìn)而轉(zhuǎn)化為對read事件可行性的約束,read事件的可行性約束要求read事件讀取的值與原執(zhí)行軌跡中在此read事件之前發(fā)生、距離此read事件最近且與此read事件操作同一共享變量的write事件的值相同;
在對branch事件建立可行性約束時(shí),若假定branch事件的可行性依賴于同一線程內(nèi)部在branch事件之前所有的read事件,則會(huì)引入一些不必要的read事件的可行性約束;實(shí)際程序執(zhí)行時(shí),branch事件讀取的共享變量的值來自同一線程內(nèi)在branch事件之前且離branch事件最近,讀同一共享共享變量的read事件的值;因此為確保branch事件讀寫共享變量的值不變,只需保證線程內(nèi)在branch事件之前的所有read事件中,如果有多個(gè)read事件操作同一共享變量,則只需確保距離branch事件最近的read事件讀的值不變,而不需要所有的read事件讀的值不變;通過這種方法可以減少對于分支事件可行性建立約束的個(gè)數(shù),從而減少約束求解的時(shí)間。
(2)約束求解
在本發(fā)明中我們借助約束求解器Z3實(shí)現(xiàn)約束的求解,將所有的約束組合并調(diào)用求解器求解方法,觀察對步驟2中得到的事件序列建立的約束求解是否有解,若有解則說明存在執(zhí)行軌跡可以按照這種不可序列化交錯(cuò)序列的順序執(zhí)行事件序列中的三個(gè)事件,即此潛在的可能會(huì)引起不可序列化交織的事件序列是一個(gè)真實(shí)的原子違背。
以上所述僅是本發(fā)明的優(yōu)選實(shí)施方式,應(yīng)當(dāng)指出,對于本技術(shù)領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明原理的前提下,還可以做出若干改進(jìn)和潤飾,這些改進(jìn)和潤飾也應(yīng)視為本發(fā)明的保護(hù)范圍。