• 沒有找到結果。

R EACHABILITY T ESTING AND D YNAMIC E FFECTIVE T ESTING

1.   簡介

1.7   R EACHABILITY T ESTING AND D YNAMIC E FFECTIVE T ESTING

reachability testing 是一種用來測試並行程式非決定性行為的方法,架構上揉合了 nondeterministic testing 與 deterministic testing 兩者的概念;透過 reachability testing,

系統開發人員可以確認並行程式執行的正確與否

Figure 1.5 Reachability testing 架構圖

reachability testing 整個測試過程如 Figure 1.5 可粗分成兩個階段:monitor phase

Execution P with input X

Race analyzer (To derive race-variants)

Prefix-based replay of R

… … ……

A SYN-sequence S

Queue to store race variants

Derived race variants

Remove a race variant R from queue

Obtain a SYN-sequence

13

與 replay phase。在 monitor phase 中,受測程式的執行如同 nondeterministic testing 一般,是完全不受控制的,系統的排程可自由地組合任何可能 SYN-sequence 並 完成執行。對於 reachability testing 整體架構而言,monitor phase 所需要作的僅是 將受測程式執行的 SYN-sequence 記錄下來,供作後續的分析與執行需要。顧名 思義,replay phase 的目的即在重現前次的執行,它應用 deterministic testing 的概 念,受測程式在執行時需要指定 synchronization events 的 partially order 關係,藉 由 reachability testing 提供的協定,將所有 synchronization events 按指定的次序執 行。

很明顯地,單純地實作 monitor phase 與 replay phase 並不能解決 nondeterministic

testing 與 deterministic testing 的不足,reachability testing 因此導入了 race analyzer 的機制,將 monitor phase 與 replay phase 作完美的結合。Race analyzer 的主要工 作在於從 monitor phase 記錄的 SYN-sequence 中,分析出其他不同於此

SYN-sequence 但又可能出現的 partially order 關係,稱作 race variant。換言之,race analyzer 可藉由更動 SYN-sequence 中部分 synchronization events 的 partially order 關係用以產生 race variants;由於在被更動點之後的 synchronization events 已無法 保證其執行的必然性(例如:經由不同的執行順序,執行過程中可能會產生不同 的變數值,而這些變數值可能會作為程式中 conditional branch 的依據,並決定部 分程式碼的執行與否);相對於 SYN-sequence,race variants 將不再代表某次完整 的執行順序,而是某個執行順序中最前面的一部分;當要進行受測程式的整個執

14

行時,必須將 replay phase 作一個適當的調整。

前面提到的 replay phase 僅是應用 deterministic testing 的概念,但由於指定的

partially order 關係 race variant 是一個不完整的執行過程,reachability testing 因此 提出 prefix-based replay 的概念,透過在 race variant 中加入一個特殊標記的方式,

使 replay phase 時得知 race analyzer 更動的 partially order 的位置,當 replay 的過 程中遇到前述的特殊標記,reachability testing 立刻切換到 monitor 模式,改由系 統排程自由地產生可能的執行順序,執行受測程式中之後的部分,並將此記錄下 來形成另一個不同的 SYN-sequence 再交由 race analyzer 分析、產生其它新的 race

variants。由此可見,reachability testing 利用這樣反覆的動作,一開始將第一次執 行得到的 SYN-sequence 從頭開始對每一個 partially order 關係作更動,產生一些

race variants,並標示更動的位置;在後續的 race analyzer 進行過程中,特殊標記 前的 partially order 將不再被更動,因此隨著 reachability testing 中每一輪的執行,

標記的位置會逐步地向受測程式結尾處靠近。當特殊標記到達程式結尾,race

analyzer 將不再產生任何新的 race variants,整個 reachability testing 過程也在執行 完所有的 race variants 後結束。最後,為了達到完整測試的目的,race analyzer 所 採用的演算法必須能保證所有受測程式可能產生的 race variants 都會在測試過程 中產生,另外由於效率上的考量,演算法同時也要儘量避免產生重複的 race variants。

對於 reachability testing,race analyzer 所採用的演算法是整體效能的關鍵,

15

SYN-sequence 的記錄格式也常因 race analyzer 的需要及程式存取機制上的差別

(如:shared-memory, message-passing, semaphore, …etc)而有所不同。黃冠寰博 士於 1995 年首先提出了利用建構 RV-diagram 的方式,並以 shared-memory 與

semaphore 兩種存取機制為例子作演示。RV-diagram 是一個 n-ary 的樹狀結構,其 中 n 代表整個受測程式中並行程序的個數。由 RV-diagram 的 root 到樹狀結構中任 一個節點的路徑都分別代表了此受測程式中一部分 synchronization events 間

totally order 的關係。在 reachability testing 執行過程中,每個相異的 SYN-sequence 都分別會產生各自的 RV-diagram,並在展開的過程中標記出代表 race variant 的節 點。之後黃冠寰博士在 2004 年於 IEEE Transaction on Software Engineering 發表以 race graph 的方式,直接更改 Synchronization events 間 partially order 的關係。在 race graph 中每一個節點都代表程式中某一個 Synchronization event,

Synchronization events 間的 partially order 關係則用 directed edge 表示。產生 race variants 時,僅需要分別就某一節點的 in-edge 作反向即可;若某一節點一共有 k 個 in-edge,則在此節點的位置上,至多會產生(sk-1)個 race variants。實驗上相較 於 RV-diagram,race graph 的方法能大幅提高效能,對於某個 SYN-sequences 總數 為 117 的並行程式,RV-diagram 的方式一共需要 3,537 次的執行,而 race graph 僅僅需要 152 次。那是因為 RV-diagram 所產生的 race variants 容易造成重複的測 試,即產生相同的 SYN-sequence。

16

Figure 1.6 利用 race graph 產生 race variant

雖然 reachability testing 已實證能完整地測試並行程式的非決定性行為,並在效能 上取得長足的進步,但其基礎架構上卻存在一嚴重的不足。在前面提到,

reachability testing 在 monitor 的過程中並不對受測程式的執行進行任何干預,因 此當程式中出現無窮迴圈或忙碌等待迴圈(busy-waiting loops)時,reachability testing 很容易因為執行無法順利結束,導致 prefix-based replay 的過程中失敗。

“a” is a shared variable.

Process 0 Process 1

Reverse direction of in-edges Remove some nodes

There is a loop.

P0 P1

17

...

Figure 1.7 造成 Reachability testing 問題的受測程式之一

Figure 1.7 是一個由兩個程序 process 0 與 process 1 組成的並行程式,在 process 0 中有三行程式碼:S0,0, S0,1 與 S0,2,而 process 1 中由一行程式碼 S1,0 組成。這 邊很明顯地可以看到:程式的執行將會在 S0,1 與 S0,2 不斷地來回,{S0,0, S1,0, S0,1, S0,2, …}是其中一個可能產生的執行順序。就如前面所敘述 reachability testing 的架構,執行時產生的順序將會被記錄下來,提供後續的 race analyzer 作 分析的動作;但在以{S0,0, S1,0, S0,1, S0,2, …}為首的執行順序時,程式將會進入 無窮的等待迴圈之中,不斷地記錄的執行順序,最終耗盡系統所有可用的記憶體 空間。

“a” is a shared variable and its initial value is 0.

Process 0 Process 1

Figure 1.8 造成 Reachability testing 問題的受測程式之二

另外一個潛在的問題是:有時程式的執行並沒有進入無窮迴圈之中。以 Figure 1.8 為例:受測程式最快可能只執行三行的程式碼{S1,0, S0,0, S0,1}就結束,也有可能

18

多在迴圈裡執行一次,得到{S0,0, S0,1, S1,0, S0,0, S0,1}這樣的執行順序。很明顯 地,process 0 中的迴圈 S0,0, S0,1 必須不斷地執行忙碌等待迴圈直到 process 1 中 的 S1,0 獲得執行;有別於無窮迴圈 Figure1.8 的例子最終必定會因為操作系統排 程給 process 1 而執行結束。但是在 reachability testing 的架構之下,race analyzer 為達到完整測試的目的,會將所有程式可能的執行順序全部產生,因此無論是執 行迴圈 S0,0, S0,1 一次、兩次,甚至是無限多次的執行順序,都會因為 race analyzer 視作相異的 race variants 而逐一地付予執行。我們可以把這些產生的 race variants 表達成{(S0,0, S0,1,)i S1,0, S0,0, S0,1}的形式,其中 i 可以是大於或等於零的任意 整數,而這些 race variants 將使得存放 race variants 的佇列永遠無法被清空,整個

reachability testing 將因而沒有結束的時候。

前面以一個最簡單的例子說明非無窮迴圈可能的問題,其中反覆執行的部分 S0,0,

S0,1 都在同一個程序中,Figure1.9 是另一個較複雜的例子,反覆執行的部份將橫 跨兩個不同的程序。在 Figure 1.9 造成 Reachability testing 問題的受測程式之三中 最短的可能執行序列是{S1,0, S0,0, S0,1, S1,1},和前述例子類似,這個例子中所 有可能的執行序列可以表達成:{(S0,0, S1,0, S0,1, S1,1,)i S1,0, S0,0, S0,1, S1,1},

其中 i 是大於或等於零的任意整數;可能重複執行的部分為 S0,0, S1,0, S0,1, S1,1,

分別屬於 process 0 與 process 1。

“a” is a shared variable.

Process 0 Process 1

19

...

S

0,0 DO { a = 1;}

S

0,1 WHILE(a==0)

...

...

S

1,0 DO { a = 0;}

S

1,1 WHILE(a==0)

...

Figure 1.9 造成 Reachability testing 問題的受測程式之三

Multi-core 系統的測試驗證有以下困難點: Shared variables 的存取造成 race condition 除了、具迴圈,還有 Task priority,分成以下三個部分來進行研究:

處理迴圈程式可能造成的問題,在 prefix-based replay 時要能將已陷入無窮迴圈的 受測程式強制結束,並回報可能造成無窮迴圈的部分程式碼與特定的執行順序。

其次,在 race analyzer 的部分應發展能處理忙碌等待迴圈的演算法,避免產出過 多的 race variants,導致無窮的測試。

1.8 Example of an Non-deterministic Web Services

相關文件