覆蓋測試中高效代碼插樁技術(shù)的研究
2.1 CodeTest 工具的插樁技術(shù)分析
Codetest 的插樁過程簡單來說分為兩步:
(1)對源代碼進行預編譯;被測程序首先會通過CodeTest 的編譯驅(qū)動器調(diào)用程序的原編譯器進行預編譯,通常是進行宏替換。
(2)對預編譯后的文件進行插樁,生成插樁后的.C 文件和.IDB 的插樁符號數(shù)據(jù)庫文件;預編譯完成后,CodeTest的插裝器(即源代碼分析程序)據(jù)不同的參數(shù)對預編譯后的源代碼進行相應方式的自動插樁,即在需要插樁的位置寫入一條賦值語句(如:amc_ctrl=0x74100010),并把插入的標記送入數(shù)據(jù)庫文件中生成一個符號數(shù)據(jù)庫暫存起來,為以后的分析時調(diào)用。然后,CodeTest的編譯驅(qū)動器會調(diào)用原編譯器對插樁后的代碼進行編譯生成可執(zhí)行目標代碼送到目標板上運行。當程序在目標系統(tǒng)運行到插樁點的位置時,目標板的控制總線和地址總線上會出現(xiàn)相應的控制信號和地址信號。當 CodeTest的輔助硬件(信號捕獲探頭)從控制總線和地址總線上監(jiān)視到符合以上條件的信號時,CodeTest會主動地從數(shù)據(jù)總線上把數(shù)據(jù)捕獲回來送到CodeTest的內(nèi)存中暫存并對這些數(shù)據(jù)進行預處理,然后將預處理后的數(shù)據(jù)通過局域網(wǎng)送到工作平臺上。通過與前面生成的符號數(shù)據(jù)庫中的數(shù)據(jù)進行比較,我們就此得知當前程序的運行狀態(tài),借此完成對嵌入式軟件的性能分析,高級覆蓋率分析,內(nèi)存分析和大容量的代碼跟蹤。
CodeTest是一個硬件輔助軟件的測試與分析工具,它吸取軟件打點技術(shù),并對這種技術(shù)進行了改善,純軟件工具插入的是一個函數(shù),而 CodeTest插入的是一條賦值語句,它在匯編級也是一條語句,所以它執(zhí)行的時間非常短,占用的空間也非常少,同時避免了被其它的中斷所中斷,所以它對目標系統(tǒng)的影響非常?。?%-15%)。
2.2 程序插樁的切入點
CodeTest 作為一種商品,很多技術(shù)不對外公開 ,但是我們?nèi)钥梢悦靼灼洳鍢兜脑?,進而以此為參考對插樁技術(shù)做進一步的研究;在國內(nèi),雖有很多工具使用了插樁技術(shù),但是都不夠高效, 為了方便研究我們選擇GCC 作為插樁技術(shù)研究的平臺。
GCC 是一個高度優(yōu)化,高度可移植,且廣泛使用的編譯系統(tǒng)。它能處理多種語言,包括C/C++、Fortran、Java、Ada 等多種語言前端,而且后端幾乎支持所有的處理器結(jié)構(gòu)。同時GCC作為源碼開放的軟件,可以自由修改和使用。
圖1 是GCC 增加插樁階段后的編譯流程。
GCC 編譯器的工作流程大致可以分為前端、中端和后端。中端Gimple 層是高版本GCC 中新增加的,是用來對經(jīng)過詞法、語法分析后的程序進行優(yōu)化和整理的階段,我們這里可以暫時忽略這個階段。前端包括預處理和詞法、語法分析。
預處理通常是做宏替換處理。詞法、語法分析的輸入是預處理后的文件,輸出是AST ,AST 經(jīng)過優(yōu)化后產(chǎn)生Gimple Tree,然后交給RTL 模塊去處理。RTL(Register Transfer Language)是一種中間語言,作為編譯器工作的后端,是GCC內(nèi)部使用的一種能對實際體系結(jié)構(gòu)作抽象的,與硬件無關(guān)的語言。在GCC 中將生成的中間代碼表達式以一種雙向鏈表的形式組織起來的,在鏈表中有一些特殊的節(jié)點,這些節(jié)點記錄了程序的結(jié)構(gòu)信息。
GCC 編譯器前端的工作完成后,詞法語法分析器已經(jīng)識別完程序的所有特征,因此將詞法、語法分析至Gimple 這個階段作為代碼插樁的切入點是完全可行的。然后,GCC 利用中間代碼生成會匯編代碼時,如果掃描到RTL 中的特殊節(jié)點就會根據(jù)用戶的需要適當?shù)牟迦胍恍┩瓿尚畔⒉杉δ艿膮R編代碼行,從而就可以實現(xiàn)代碼插樁。但是這種做法有兩個缺點:一是代碼的插樁和編譯器的結(jié)合很緊密,并且在匯編代碼的生成過程中需要針對不同的CPU 生成不同的匯編代碼,與CPU 的關(guān)聯(lián)性很強,不便于移植;而是,當程序很大時,探針的植入會造成代碼的膨脹,及進行信息采集的代碼的插入就需要很多時間。
評論