循环结构的数据流分析方法
一 引言
??????? 在測(cè)試人員對(duì)代碼文件進(jìn)行靜態(tài)分析過(guò)程中,數(shù)據(jù)流分析占有舉足輕重的作用,很多重要的信息,比如不可達(dá)語(yǔ)句、DU、DD、UR…等都是基于數(shù)據(jù)流分析的結(jié)果而得出的。以往,數(shù)據(jù)流分析通常是由測(cè)試人員人工完成。測(cè)試者在理解代碼邏輯的基礎(chǔ)上,從被分析代碼的起點(diǎn)跟蹤數(shù)據(jù)的流向,直到到達(dá)被分析代碼的終點(diǎn)。這項(xiàng)工作看起來(lái)簡(jiǎn)單,但是實(shí)際做起來(lái)卻往往令測(cè)試人員感到非常頭疼。主要原因有三點(diǎn):1.數(shù)據(jù)的變化要隨著路徑長(zhǎng)度的增加不斷累積;2.分支條件要隨著路徑的增長(zhǎng)不斷累積,并且路徑上每增加一個(gè)分支節(jié)點(diǎn),都要在路徑中最新的數(shù)據(jù)分析結(jié)果的基礎(chǔ)上計(jì)算分支條件的值; 3.路徑數(shù)通常隨著代碼規(guī)模的增長(zhǎng)以幾何級(jí)數(shù)的速度增長(zhǎng)。無(wú)論是數(shù)據(jù)變化結(jié)果的累積還是分支條件的累積或者路徑數(shù)的增長(zhǎng),當(dāng)任何一個(gè)累計(jì)到一定數(shù)量的時(shí)候,對(duì)于人腦來(lái)說(shuō),在進(jìn)行跟蹤與分析就成為一件不可能完成的任務(wù)了。所以在實(shí)際的工作中,測(cè)試人員的通常做法就是盡力而為,能分析多少就分析多少。這就使很多隱藏在代碼中的很多問(wèn)題在測(cè)試人員面前逃之夭夭。
?????? 隨著計(jì)算機(jī)技術(shù)的不斷發(fā)展,各行各業(yè)的信息化工作也進(jìn)行得如火如荼。“讓電腦代替測(cè)試人員進(jìn)行數(shù)據(jù)流分析”也不斷的被提到測(cè)試行業(yè)的信息化工作當(dāng)中。然而卻一直進(jìn)展緩慢,始終達(dá)不到工程應(yīng)用的水平。最主要的攔路石有兩塊:1 代碼中的循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析;2代碼中的函數(shù)調(diào)用語(yǔ)句的數(shù)據(jù)流分析。本文闡述的分析方法能夠準(zhǔn)確高效的完成循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析。關(guān)于函數(shù)調(diào)用語(yǔ)句的數(shù)據(jù)流分析方法在另外一篇文章中闡述。
?
二 基本概念
??????? 在介紹具體方法之前,先交代涉及的主要的概念。代碼的數(shù)據(jù)流分析,顧名思義就是對(duì)一段代碼中從起點(diǎn)到終點(diǎn)數(shù)據(jù)流動(dòng)的全過(guò)程進(jìn)行分析。在數(shù)據(jù)流動(dòng)的過(guò)程中,可能會(huì)出現(xiàn)數(shù)據(jù)定值,也可能會(huì)出現(xiàn)數(shù)據(jù)引用。同時(shí),由于代碼中有可能會(huì)存在多種分支語(yǔ)句,因此,從起點(diǎn)出發(fā),會(huì)產(chǎn)生一條或者多條路徑,每條路徑中由多個(gè)節(jié)點(diǎn)組成,每個(gè)節(jié)點(diǎn)對(duì)應(yīng)相應(yīng)的約束條件,除此之外,每個(gè)節(jié)點(diǎn)還對(duì)應(yīng)著到達(dá)該節(jié)點(diǎn)之前所有的變量應(yīng)用的最終結(jié)果,我們將其稱之為數(shù)據(jù)切片。隨著路徑長(zhǎng)度的增長(zhǎng),約束條件不斷累積,在到達(dá)終點(diǎn)之前,如果約束條件的取值為永假,則路徑終止,此路徑為不完整路徑,如果順利到達(dá)終點(diǎn),則此路徑為完整路徑。由于本文闡述的是循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析方法,所以有必要介紹循環(huán)相關(guān)的概念。循環(huán)的入口條件表達(dá)式如果是可計(jì)算的,或者循環(huán)中的跳出語(yǔ)句的約束條件集合是可求值的話,則循環(huán)為正常結(jié)束循環(huán);否則的話,在數(shù)據(jù)流分析過(guò)程中,為了避免無(wú)意義的循環(huán)導(dǎo)致路徑的無(wú)限延長(zhǎng),本文闡述的方法會(huì)設(shè)定一個(gè)閾值,如果不是正常結(jié)束循環(huán),當(dāng)循環(huán)次數(shù)超過(guò)閾值后,強(qiáng)制令循環(huán)終止,這樣的循環(huán)稱之為強(qiáng)制結(jié)束循環(huán)。循環(huán)中的語(yǔ)句和循環(huán)后的語(yǔ)句由于可能受到循環(huán)所造成的數(shù)據(jù)變化的影響,稱之為循環(huán)相關(guān)語(yǔ)句。
?
三 循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析
?????? 對(duì)于沒(méi)有循環(huán)結(jié)構(gòu)和函數(shù)調(diào)用語(yǔ)句的代碼段,目前已經(jīng)形成了比較成熟的數(shù)據(jù)流分析方法,循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析是對(duì)普通數(shù)據(jù)流分析方法的改進(jìn)。
1 普通的數(shù)據(jù)流分析方法
??????? 對(duì)于沒(méi)有循環(huán)和函數(shù)調(diào)用的代碼段,一般的數(shù)據(jù)流分析方法包括變量應(yīng)用分析、構(gòu)建塊樹、建立控制流圖、遍歷路徑等幾個(gè)步驟。
- 變量應(yīng)用分析
??????? 在語(yǔ)法分析的基礎(chǔ)上,對(duì)在代碼中發(fā)生定值及引用的語(yǔ)句進(jìn)行分析,并將定值及引用的變量及其具體值按照發(fā)生的順序進(jìn)行記錄。注意,一定要按照順序記錄,因?yàn)椴煌捻樞驎?huì)產(chǎn)生不同的數(shù)據(jù)結(jié)果。
- 構(gòu)建塊圖
??????? 在詞法分析、語(yǔ)法分析的基礎(chǔ)上,以代碼段起始點(diǎn)為根節(jié)點(diǎn),分析代碼段中各分支語(yǔ)句如if、else if、for、 while、case…等分支語(yǔ)句以及break 、exit、 return…等強(qiáng)制轉(zhuǎn)向語(yǔ)句的層次關(guān)系及先后關(guān)系,從而構(gòu)建成一顆樹,通常會(huì)將帶有函數(shù)調(diào)用的語(yǔ)句處理為普通語(yǔ)句,不做為單獨(dú)的一個(gè)塊來(lái)處理。
- 建立控制流圖
??????? 在塊樹構(gòu)建完成后,從根節(jié)點(diǎn)開(kāi)始,以根節(jié)點(diǎn)作為源點(diǎn),按照子塊的先后順序及層次關(guān)
系對(duì)子塊進(jìn)行分析,根據(jù)每個(gè)子塊的具體類型建立其所有目標(biāo)節(jié)點(diǎn),所有塊分析完畢后,將會(huì)構(gòu)建成特定代碼段的控制流圖。
- 遍歷路徑
??????? 從控制流圖的源點(diǎn)開(kāi)始,使用深度優(yōu)先搜索遍歷圖中所有路徑,路徑邊上面的變量應(yīng)用都要記錄到數(shù)據(jù)切片上。以最新的數(shù)據(jù)切片為基礎(chǔ),在遍歷的過(guò)程中不斷計(jì)算各節(jié)點(diǎn)累積約束條件的邏輯值,計(jì)算并記錄下每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的最新的數(shù)據(jù)切片,獲取所關(guān)注的數(shù)據(jù)流分析結(jié)果。
?
2 循環(huán)結(jié)構(gòu)數(shù)據(jù)流分析
?????? 要對(duì)循環(huán)結(jié)構(gòu)進(jìn)行正確的數(shù)據(jù)流分析,前提是正確的繪制for,while, do,break, continue等循環(huán)相關(guān)塊的控制流圖。在此基礎(chǔ)上,本文分別介紹正常結(jié)束循環(huán)和強(qiáng)制結(jié)束循環(huán)兩種情況下的數(shù)據(jù)流分析方法。
- 正常結(jié)束循環(huán)
?????? 如果循環(huán)是正常結(jié)束循環(huán),那么就按照正常的數(shù)據(jù)流分析即可。相較于普通的數(shù)據(jù)流分析方法,所不同就是路徑隨著循環(huán)次數(shù)的增加不斷延長(zhǎng),直至循環(huán)結(jié)束。
- ?強(qiáng)制結(jié)束循環(huán)
?????? 由于循環(huán)被強(qiáng)制結(jié)束,所以每條路徑的最新的數(shù)據(jù)切片、約束條件集合都是不準(zhǔn)確的。理論上說(shuō),循環(huán)相關(guān)的語(yǔ)句都是不能夠進(jìn)行正確的數(shù)據(jù)流分析了,包括循環(huán)中的語(yǔ)句和循環(huán)后的語(yǔ)句。可循環(huán)相關(guān)語(yǔ)句的數(shù)據(jù)流分析往往非常重要,所以只能盡力而為了。通過(guò)對(duì)循環(huán)結(jié)構(gòu)內(nèi)部的數(shù)據(jù)分析,我們能夠獲取循環(huán)內(nèi)部數(shù)值可能會(huì)發(fā)生變化的變量集合,這個(gè)集合可以看成是當(dāng)前強(qiáng)制結(jié)束循環(huán)所造成的數(shù)據(jù)結(jié)果。在路徑遍歷過(guò)程中,如果到達(dá)了循環(huán)相關(guān)語(yǔ)句中的分支語(yǔ)句,暫時(shí)可將循環(huán)視而不見(jiàn),認(rèn)為其不存在,對(duì)分支語(yǔ)句的分支條件進(jìn)行變量分析,如果該條件中使用了循環(huán)內(nèi)部的定值集合中的變量,則認(rèn)為其可取任意值,不進(jìn)行分支條件的數(shù)值檢測(cè),所有分支路徑都遍歷。如果該條件中沒(méi)有使用循環(huán)內(nèi)部的定值集合中的變量,則進(jìn)行正常的數(shù)據(jù)流分析。如此,能夠?qū)?qiáng)制結(jié)束循環(huán)的循環(huán)相關(guān)語(yǔ)句中的相當(dāng)一部分進(jìn)行必要的數(shù)據(jù)流分析。
?
四 具體應(yīng)用
?????? 在測(cè)試之家開(kāi)發(fā)的ufinder(不可達(dá)語(yǔ)句檢測(cè)工具)V0.97中應(yīng)用了上文闡述的對(duì)循環(huán)結(jié)構(gòu)的數(shù)據(jù)流分析分析方法,相對(duì)于一般的數(shù)據(jù)流分析,在ufinder中對(duì)數(shù)據(jù)流分析進(jìn)行了一定程度的簡(jiǎn)化,主要有兩點(diǎn):1.數(shù)據(jù)切片中僅僅存儲(chǔ)變量的定值,而沒(méi)有存儲(chǔ)變量的引用;2.遍歷過(guò)程中如果找到一條完整路徑,說(shuō)明存在一條可達(dá)路徑,遍歷過(guò)程立刻停止;通過(guò)實(shí)際工程應(yīng)用的檢驗(yàn),本文闡述的方法確實(shí)能夠準(zhǔn)確高效且全面地對(duì)包含有函數(shù)調(diào)用語(yǔ)句的代碼段進(jìn)行數(shù)據(jù)流分析。
?
?
?
總結(jié)
以上是生活随笔為你收集整理的循环结构的数据流分析方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 简易计时器的设计与实现-DE2|VHDL
- 下一篇: 计算机的flash player在哪里,