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