軟件分析筆記:2.數據流分析


1數據流分析基礎

1.1停機問題-抽象方法

針對基礎篇中的停機問題,我們可以試用抽象方法去嘗試解決問題。邪惡程序存在的關鍵在於程序中有if存在 。因此可以采取以下方式。

1.1.1忽略掉所有程序的if條件部分

void Evil(){
	if(!Halt(Evil))return;
	else while(1)
}

抽象成

void Evil(){
	向左走return;
	向右走while(1);
}

語義:“向左走/向右走”為非確定性選擇,程序隨機從“向左走” 和“向右走”后面的語句中選擇一條執行。

1.1.2忽略所有條件判斷中的條件,一律抽象為不確定選擇

void Evil(){
	再來一次
	向左走goto再來一次;
	向右走return;
}

1.1.3抽象過程分析

針對給定輸入

  • 原始程序只有一條執行路徑,抽象程序上有多條執行路徑
  • 原始程序的執行路徑一定包含在抽象程序的執行路徑中

停機問題

  • 原始程序停機:存在自然數n,程序的執行路徑長度 小於n
  • 抽象程序停機:存在自然數n,程序中所有執行路徑 的長度都小於n

1.1.4停機問題的判定方法

繪制控制流圖(結點為程序語句,邊為語句間的轉移 ), 如果控制流圖上有環,則可能不終止,否則一定終止。

1.2符號分析

1.2.1分析內容

給定一個只包含浮點數變量和常量的程序,已知輸入的符號,求輸出的符號。

1.2.2符號分析的抽象

抽象符號

  • 正 ={所有的正數}
  • 零={0}
  • 負= {所有的負數}
  • 槑={所有的整數和NaN}

1.2.3符號分析的基本思路

給定程序的一條執行路徑,我們能推出結果符號的抽象取值。

給定程序的兩條執行路徑,我們得到兩個結果符號的抽象取值 𝑣1,𝑣2,我們可以用如下的操作來合並這兩個值:

如果我們能知道程序所有可能的路徑產生的結果 符號𝑣1,𝑣2,…,我們就知道了程序的最終結果⊓ (𝑣1,𝑣2,… )。

如何知道程序有哪些可能的路徑?

  • 近似方案1:忽略掉程序的條件判斷,認為所有分支 都有可能到達 .

如何能遍歷所有可能的路徑?

  • 近似方案2:不在路徑末尾做合並,在控制流匯合的 所有位置提前做合並

1.3數據流分析單調框架

目標:通過配置框架的參數,可以導出各種類型 的算法,並保證算法的安全性、終止性、收斂性。

1.3.1名詞解釋

半格(semilattice)

半格是一個二元組(S,⊓),其中S是一個集合,⊓ 是一個交匯運算,並且任意𝑥,𝑦,𝑧 ∈ 𝑆都滿足下 列條件:

  • 冪等性idempotence: 𝑥 ⊓ 𝑥 = 𝑥
  • 交換性commutativity: 𝑥 ⊓ 𝑦 = 𝑦 ⊓ 𝑥
  • 結合性associativity: 𝑥 ⊓ 𝑦 ⊓ 𝑧 = 𝑥 ⊓ (𝑦 ⊓ 𝑧)
  • 存在一個最大元⊤,使得𝑥 ⊓ ⊤ = 𝑥

偏序Partial Order

偏序是一個二元組(S, ⊑),其中S是一個集合, ⊑ 是一個定義在S上的二元關系,並且滿足如下性質:

  • 自反性:∀𝑎 ∈ 𝑆:𝑎 ⊑ 𝑎
  • 傳遞性:∀𝑥,𝑦,𝑧 ∈ 𝑆:𝑥 ⊑ 𝑦 ∧ 𝑦 ⊑ 𝑧 ⇒ 𝑥 ⊑ 𝑧
  • 非對稱性:𝑥 ⊑ 𝑦 ∧ 𝑦 ⊑ 𝑥 ⇒ 𝑥 = 𝑦

每個半格都定義了一個偏序關系

  • 𝑥 ⊑ 𝑦當且僅當𝑥 ⊓ 𝑦 = 𝑥

1.3.2半格示例

抽象符號域的五個元素和交匯操作組成了一個半格,

半格的笛卡爾乘積(𝑆 × 𝑇,⊓𝑥𝑦)還是半格

任意集合和交集操作組成了一個半格

  • 偏序關系為子集關系
  • 頂元素為全集

任意集合和並集操作組成了一個半格

  • 偏序關系為超集關系
  • 頂元素為空集

半格和偏序關系

每個半格都定義了同一集合SSS上的一個偏序關系

例如,正整數集合上的"求最小公倍數運算"是半格,而"整除關系"是對應的偏序。

又如,任意集合和"交集操作"組成了一個半格,頂元素是全集,而"子集關系"是對應的偏序。

又如,任意集合和"並集操作"組成了一個半格,頂元素是空集,而"超集關系"是對應的偏序。

半格的高度

定義: 半格的偏序圖中任意兩個結點 的最大距離+1。


1.3.3單調(遞增)函數 Monotone (Increasing) Function

定義:給定一個偏序關系(𝑆,⊑),稱一個定義在𝑆上的 函數𝑓為單調函數,當且僅當對任意𝑎,𝑏 ∈ 𝑆滿足

  • 𝑎 ⊑ 𝑏 ⇒ 𝑓 (𝑎) ⊑ 𝑓 (𝑏)
  • 注意:單調不等於a ⊑ 𝑓 (𝑎)

單調函數示例

  • 在符號分析的半格中,固定任一輸入參數,抽象符號 的四個操作均為單調函數
  • 在集合和交/並操作構成的半格中,給定任意兩個集 合GEN, KILL,函數𝑓 (𝑆) =( 𝑆 − 𝐾𝐼𝐿𝐿) ∪ GEN為單調函 數

1.3.4數據流分析單調框架

  • 一個控制流圖(𝑉,𝐸)
  • 一個有限高度的半格(𝑆,⊓)
  • 一個entry的初值𝐼
  • 一組結點轉換函數,對任意𝑣 ∈ 𝑉 − 𝑒𝑛𝑡𝑟𝑦存在 一個結點轉換函數𝑓v

算法偽代碼:

2.數據流分析應用

2.1Reaching Definitions可達定值分析

2.1.1原理

如下圖所示,我們在p點定義了一個變量v,在p到q的路徑中,如果v被重新定義了,那么我們就說這個變量被“殺死了”,如果變量沒有被殺死,那么v的值就可以順利傳導到q點。可達定值分析常常用來判斷某個已經被聲明的變量是否被使用過。

2.1.2分析過程

我們繼續使用Abstract和safe-approximation兩步驟來進行可達定值分析。

  • Abstraction:將所定義的每個變量狀態用bit vectors來表示,如下圖所示:

  • Safe-approximation:我們假設有一個聲明D: v = x op y,這條語句新增了一個對於v的聲明,並殺死了所有其他對於v的聲明,語句的其他部分不受影響。轉換函數如下:

    一個簡單的實例如下所示:

    每個基本塊誕生和殺死的聲明如上圖所示,這個很好理解。

2.1.3可達定值分析的偽代碼

我們先將所有BB的輸出設置成空,然后利用我們的轉換函數對於每一個BB的輸入輸出進行迭代,在一次迭代過程中如果有BB的輸出發生變化則進行下一次迭代,直到所有BB的輸出都不變為止。

may analysis一般都初始化為空,must analysis一般都初始化為Top

2.1.4可達定值分析實例

如下圖所示是一個可達分析的實例,可以自己試着按照上面的偽代碼做一下分析,看最終的結果是什么。

最終結果是:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM