[論文解讀] Cross-Entropy Based Testing

Cross-Entropy Based Testing

簡介

論文標題

  • Cross-Entropy Based Testing
  • 基於交叉熵的測試

簡介

  • 將代碼的執行順序分解成圖,
  • 不同的線程在節點上有其離散的概率分佈表.
  • 根據概率選擇某個線程執行,收集足夠多的樣本,根據數據樣本更新概率分佈
  • 迭代,直到達到性能函數最優,或者標準差低於某個閾值

交叉熵應用在:假定每個節點有個理想分佈,該分佈最容易發現問題.然後從原始分佈開始,利用交叉熵逐步逼近理想分佈.因爲理想分佈是未知的,所以是通過採樣的方式去求每次的分佈

以上爲個人理解,其實我也沒搞懂到底怎麼回事

摘要

主要問題: 增加測試的窮盡性減少未檢測錯誤的數量是軟件測試的主要問題。

在本文中,我們提出了一種基於交叉熵方法的新的軟件測試方法.我們定義了一個性能函數,它在我們尋找的錯誤或模式的鄰域中更高。然後,程序被執行多次,從一些隨機分佈中選擇輸入向量。起始分佈通常是均勻的,並且它在每次迭代中根據在前一次迭代中性能函數的最高值的向量而改變。

交叉熵方法被證明在估計罕見事件的概率尋找困難優化問題的解決方案方面非常有效。

基於交叉熵(Cross-Entropy )CE:又稱KL距離或KL散度

實現工具: ConCEnter

介紹

CE 測試方法流程

CE 測試方法包括一個迭代過程,其中每個迭 代包括兩個階段:

1)根據指定的機制生成隨機數據樣本。

2)基於數據更新隨機機制的參數,以在下一次迭代中產生“更好”的樣本,其中根據預定義的性能函數

選擇“更好”。

根據預定義的性能函數評估樣本。當生成“最佳”樣本,即具有性能函數最大值的樣本(或者,如果全局

最大值事先未知,則具有足夠小的相對偏差)時,該過程終止。

用途舉例

爲了使 CE 方法適用,我們將焦點從搜索錯誤轉移到關注程序中最容易出錯的地方。下面的例 子有助於澄清這兩種方法之間的區別。假設我們有一個程序,我們想測試它的緩衝區溢出錯誤。面向錯 誤的測試工具搜索緩衝區溢出的執行。這些執行可能非常罕見,可能會逃過我們的測試。在交叉熵測試 中,我們將執行指向緩衝區達到最大容量的區域。這種方法的優點是,這個區域雖然可以很小,但不是可以忽略的,並且可以在隨機測試中發現。此外,如果存在緩衝區溢出的錯誤執行,它肯定發生在這個區域。

我們認爲許多常見的bug和可能包含bug的模式都有一個自然的性能函數。例如,在緩衝區溢出的情況下,執行的自然性能函數給出的值等於該執行中緩衝區的最大大小。我們將描述更多常見錯誤和錯誤模式及其相關性能函數的例子。

背景

優化問題中的交叉熵方法

交叉熵公式

D(g,h)=Eglng(X)h(X)=g(x)lng(x)dxg(x)lnh(x)dx \mathcal{D}(g, h)=E_{g} \ln \frac{g(X)}{h(X)}=\int g(x) \ln g(x) d x-\int g(x) \ln h(x) d x

衡量兩個分佈的差異,注意不是嚴格意義的距離,因爲不是對稱的

在迭代i中,我們根據當前概率分佈fi繪製了一個隨機樣本,並基於該樣本計算fif_{i}glg l之間的(近似)交叉熵。然後我們根據交叉熵的結果更新fif_i,從而構造fi+1f_{i+1}

基於CE方法對圖形優化問題的應用

我們將測試中的程序表示爲圖。然後,該圖中的路徑對應於程序的執行,並且概率被分配給邊。

性能函數

我們定義S,以便S(X)在使系統進入測試狀態的路徑上達到其全局最大值,許多常見的錯誤和錯誤模式都具有自然的性能功能。

概率更新方法
  1. 我們從統一的概率分佈開始。在每個迭代i中,我們將按其性能函數值的升序對在此迭代中生成的樣本Xi
    = {X1,…,XN}進行排序。即,S(X1)≤S(X2)≤…≤S(XN)。

  2. q<=1q <= 1
    Q(Xi)={X(1q)N,X(1q)N+1,,XN} Q\left(\mathcal{X}_{i}\right)=\left\{X_{\lfloor(1-q) N\rfloor}, X_{\lfloor(1-q) N+1\rfloor}, \ldots, X_{N}\right\}
    是其中最好的q部分,

    有小到大排序後,選取後百分之x的樣本

  3. 則概率更新公式如下
    f(e)=Q(e)Q(v) f^{\prime}(e)=\frac{|Q(e)|}{|Q(v)|}
    其中eEe∈E是起源於頂點vvGG的邊,QvQ(v)是QXiQ(\mathcal{X}_{i})中經過v的路徑,而Q(e)Q(e)QXiQ(\mathcal{X}_{i})中經過e的路徑。

  4. 當樣本的相對標準偏差低於預定義的閾值參數(通常在1%和5%之間)時,該過程終止。

備註3.1(平滑更新):在涉及離散隨機變量的優化問題(例如圖形優化問題)中,以下方程式用於更新概率函數,而不是方程式1:
f(e)=αf(e)+(1α)f(e) f^{\prime \prime}(e)=\alpha f^{\prime}(e)+(1-\alpha) f(e)
其中0<α10 <α≤1是平滑參數。顯然,對於α=1α= 1,我們有原始的更新方程。通常,使用介於0.4和0.9之間的αα值。平滑更新效果更好的主要原因是,它可以防止永遠丟失好樣本(如果在一次迭代中將其邊緣之一分配爲0)。

預備定義

目標程序: 有限的多線程程序

有限

  1. 線程數有限:t代表程序中的線程數
  2. 程序的所有執行有限:每個循環的代碼都被複制了最大次數

定義3.2(PL): Program location

程序位置(PL)是程序的展開代碼中的行號。

定義3.3 (CFGiCFG_i:control flow graph

線程ii[t]i(i∈[t])的控制流圖(CFGiCFG_i)是有向圖Gi=Li,Ei,μiG_{i}=\left\langle L_{i}, E_{i}, \mu_{i}\right\rangle
其中Li是線程的展開代碼中所有程序位置的集合.
EiE_{i}(v,u)Ei(v, u) \in E_{i}的邊集如果可以在位置v的語句之後立即執行位置u的語句,
µiLµi∈L是線程的初始程序位置。

定義3.4(PLV):Program location vector

程序位置向量(PLV) v是一個t維矢量,因此對於每個i[t]viLii \in[t] \quad v_{i} \in L_{i}。如果每個i[t]vii \in[t] \quad v_{i}是線程i中要執行的下一個程序位置,則在程序執行期間的每個時刻m,我們都說執行是在PL V 的 v處進行的。

顯然,所有PLVs的集合等於LiSL_{i} S的叉積

定義3.5(JCG):joint control graph

被測程序的聯合控制圖(JCG)是圖V,E。其頂點爲PLVs。如果存在執行路徑,其中w是u的直接後繼,則頂點u和w之間的JCG中會有一條邊。

請注意,每時每刻只有一個線程可以移動。因此,每個頂點的分支度最大爲t。由於展開了代碼,因此其中的每個語句最多執行一次,並且這些語句按其程序位置的升序執行。因此,JCG是有限有向無環圖(DAG)。
JCG的源頂點是PLV,它由每個線程i的初始PL µi組成。

定義3.6(PF)

概率函數PF:V(JCG)×P F: V(J C G) \times[t][0,1][t] \mapsto[0,1],以使每個頂點出射邊的概率總和爲1。

該函數爲每個頂點v及其每個輸出邊緣定義了線程i在執行達到v時前進的概率。如果並非所有線程都在v處啓用,我們將採用已啓用線程的相對概率。如果此時Ten[t]T_{e n} \subseteq[t]是已啓用線程的集合,則相對概率爲:
RP(v,i){PF(v,i)jTenPF(v,j) if iTen0 otherwise  R P(v, i) \doteq\left\{\begin{array}{ll} {\frac{P F(v, i)}{\sum_{j \in T_{e n}} P F(v, j)}} & {\text { if } i \in T_{e n}} \\ {0} & {\text { otherwise }} \end{array}\right.
就是把0的不要,把剩下的重新平均概率

定義3.7(可見線程狀態):Visible thread state

線程i的可見線程狀態(VTS)s是對v,σ,τ\langle v, \sigma, \tau\rangle。其中vLiv∈Li表示當前PL,σ表示所有局部變量的值,τ表示該語句在程序位置vv處訪問的全局變量的值。

直觀地,可見線程狀態集是系統訪問線程系統各個部分時可見的系統所有可能狀態。

我們假設程序中實施了正確的鎖定策略(可以靜態檢查)。因此,當僅在鎖定或解鎖語句處允許上下文切換時,任何程序執行可以達到的任何VTS,某些程序執行也可以達到的任何VTS。因此,在這種上下文切換策略下,可能具有多個後繼對象的JCG的唯一頂點是那些具有鎖定或解鎖語句程序位置的PLV。然後,可以摺疊具有單個後繼的所有頂點而不會丟失任何同步信息,因此,我們可以假定JCG圖僅包含鎖定/解鎖語句的程序位置

對於程序的單次執行,我們稱之爲JCG的頂點序列,它訪問JCG中的執行路徑。

將交叉熵用於測試

算法

算法流程

  1. 概率分佈表包含邊緣上的概率分佈,並在每次迭代時更新。最初,邊緣是未知的,因此假設分佈均勻,表爲空。
  2. 通過在同步點添加回調來檢測該程序。這使算法可以在這些點處停止執行,並確定接下來要遍歷哪個邊沿(即,哪個線程進行了移動)。在這一點上,該算法收集並存儲了JCG的邊緣知識。
  3. 在每次迭代中,該算法執行以下任務:
    1. 被分解的程序被執行多次,足以收集有意義的樣本(執行次數取決於JCG的大小)。執行被迫根據邊緣上的當前概率分佈執行調度決策。停止執行並決定下一步允許哪個線程運行是由我們實現中的單獨組件執行的。
    2. 這些執行用來計算新的概率分佈(之間計算f的公式)。參數q和α的選擇隨後討論
  4. 當前迭代的採樣樣本具有足夠小的相對標準偏差(在1%和5%之間)時,算法終止。

各部分組成

  • Instrumenter : Instrumenter是一種檢測工具,可在同步點即每個同步塊之前和之後立即添加回調
  • Decider: Decider接收被測程序的JCG的節點v,並根據控制圖邊緣上的當前相對概率RP(v)選擇允許下一步運行的線程。
  • Stopper: Stopper在已檢測代碼的回調中,它使用爲此線程指定的互斥體來停止當前正在運行的線程。然後,它在可以進行下一步(基於Decider的決定)的線程的互斥對象上調用notify
  • Evaluator: Evaluator收集執行路徑所遍歷的JCG的邊緣。在每次執行結束時,它都會計算執行的S值
  • Updater:Updater 更新程序根據評估程序的計算爲下一次迭代更新概率分佈表。

在執行期間,Decider和Evaluator收集大量數據。爲了最小化此數據的內存緩衝區的大小,它會定期寫入文件中。

改進性能的啓發式

處理展開(Dealing with unwinding):要生成展開程序的完整JCG(實際上不生成展開代碼),程序位置由原始(未展開)代碼中的行號和一個反映展開的附加參數組成。該參數是程序當前所在的所有循環的循環計數器值的向量。

減少模數(Modulo reduction):實際上,即使對於中型程序,展開程序的JCG也會很大。這個問題是雙重的。

  • 首先,圖本身可能要大兩倍才能適合內存並有效搜索。
  • 其次,更重要的是,當投影到JCG上時,在算法的每次迭代中生成的執行樣本集可能太稀疏。在這種情況下,僅針對一小部分節點更新概率。結果是該算法收斂到任意局部最大值,而不是目標全局最大值。

我們通過引入模歸約來解決這兩個問題,在模歸約中,程序位置中的計數器以一些小整數爲模來計算。模減少可從原始JCG創建模聯合控制圖(MJCG)。通過取其所有計數器的模值,JCG的每個頂點都映射到MJCG的頂點。模減少會顯着減小圖形的大小,但是,它沒有保留所需的1-1映射到展開的程序位置。我們的實驗表明,通過一些微調,可以找到最佳的模參數,其中多對一映射不會混淆CE計算,但是MJCG足夠密集以允許CE方法收斂達到全局(而非局部)最大值。

應用

  • 發現數據競爭:函數是執行期間訪問的共享資源的數量。
  • 測試錯誤路徑:函數是執行期間採用的錯誤路徑的數量。
  • 不正確使用同步原語:函數是執行中對互斥函數的調用數。
  • 引起或與等待通知情況有關的錯誤:此功能是丟失通知的數量。
  • 測試線程/任務多次失敗的恢復:該函數是取消的線程/任務的數量。
  • 觸發許多異常的環境的仿真:該函數是生成的異常的數量。
  • 無法正確釋放資源或資源池耗盡:此功能是分配的資源數量減去已釋放資源的數量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章