日韩成人黄色,透逼一级毛片,狠狠躁天天躁中文字幕,久久久久久亚洲精品不卡,在线看国产美女毛片2019,黄片www.www,一级黄色毛a视频直播

一種程序調(diào)測系統(tǒng)及方法

文檔序號:6562813閱讀:195來源:國知局
專利名稱:一種程序調(diào)測系統(tǒng)及方法
技術(shù)領(lǐng)域
本發(fā)明涉及軟件調(diào)試與測試領(lǐng)域,特別涉及能夠通過形式描述調(diào)試過程來實現(xiàn)白盒測試的程序測試系統(tǒng)及方法。
背景技術(shù)
在IT產(chǎn)品研發(fā)中,軟件調(diào)試與測試占用大量工作時間,提高這兩者的工作效率將直接加快產(chǎn)品研發(fā)進度,提高這兩者工作質(zhì)量也將直接提升產(chǎn)品質(zhì)量、降低研發(fā)風險。對軟件調(diào)試與測試操作實現(xiàn)形式化描述,是提高效率的必要條件。但是,目前主流的白盒測試工具普遍只對測試操作實施形式化描述,很少把調(diào)試操作描述成腳本并將其自動轉(zhuǎn)化為測試用例來重復執(zhí)行。
目前本領(lǐng)域主要的白盒測試工具,例如針對C語言測試的CodeTest、針對C++的CppTest、針對Java的JUnit等工具,都在一定程度實現(xiàn)了測試操作的形式化描述。無論測試描述是一種腳本語言,還是采用與被測系統(tǒng)開發(fā)相同的編程語言(如JUnit就是用Java寫測試用例對Java程序做測試),都實現(xiàn)了操作過程形式化描述。當測試操作以規(guī)范語言方式記錄時,重復測試就成為可能,而且,形式化記錄有利于對操作過程進行檢視、評估,以及改進。在白盒測試中,為了根據(jù)代碼被測試覆蓋的情況來完善測試用例,需要用腳本描述測試操作。
但這些主流白盒測試工具絕大部分沒有對調(diào)試操作進行形式化描述。某些編程語言工具雖然已局部地實現(xiàn)了調(diào)試操作的形式化描述,例如在Tornado Shell中以命令行交互方式寫腳本做調(diào)試,但這種腳本更多只是為了調(diào)試功能的增強,很難被重用于測試。
將軟件調(diào)試操作轉(zhuǎn)化為規(guī)范測試腳本,存在以下瓶頸問題1、調(diào)試操作是被測系統(tǒng)運行后在線進行的,而現(xiàn)有的眾多測試工具只支持靜態(tài)方式設(shè)計用例。
當調(diào)試操作自動轉(zhuǎn)化為測試腳本時,調(diào)、測成為一體了,調(diào)試的在線特征也要求測試需要在線進行。否則,對從調(diào)試轉(zhuǎn)化來的腳本難以立即進行調(diào)整、評估及優(yōu)化。目前多數(shù)白盒測試工具沒有支持在線方式(即不重啟被測系統(tǒng))的設(shè)計用例。被測系統(tǒng)運行后,不能在線編寫和在線運行用例,也不能在線查看其運行結(jié)果并改進測試設(shè)計,最終導致調(diào)試記錄難以轉(zhuǎn)化為實用的測試用例。
2、調(diào)試操作隨意性大,很難轉(zhuǎn)化為有效的測試用例即使有一種技術(shù)能將所有調(diào)試操作都記錄為腳本,但對所有調(diào)試記錄都進行記錄又過于繁雜,而且很難維護用例。若只取局部操作,又容易喪失操作前后的相關(guān)性。同時,調(diào)試針對代碼行,因為源碼易變,同樣導致用例難于維護。
而且,調(diào)試操作很隨意,如果直白轉(zhuǎn)換同樣使測試腳本很隨意,給工作效果評估帶來困難。
第4代白盒測試方法綜合了軟件白盒測試的最佳實踐,反映了現(xiàn)今白盒測試的發(fā)展方向,屬于公共領(lǐng)域的通用方法論。根據(jù)第4代白盒測試方法的要求,測試工具應(yīng)采用一種技術(shù)能將調(diào)試操作規(guī)范地記錄下來。

發(fā)明內(nèi)容
針對現(xiàn)有技術(shù)存在的上述問題,并且為了適應(yīng)第4代白盒測試方法的要求,本發(fā)明著眼于以下幾個方面,提供了一種新的程序測試系統(tǒng)和測試方法1、采用一種語言映射技術(shù)使測試驅(qū)動能在線進行,并使用一種腳本化的打樁技術(shù)。
這樣,測試樁也能夠進行在線模擬。通過使測試驅(qū)動與測試樁的腳本化和在線化,使得測試操作可以在線進行,從而將測試設(shè)計從靜態(tài)模式轉(zhuǎn)化為動態(tài)模式。
2、把細粒度的調(diào)試轉(zhuǎn)換為粗粒度的檢視。
由于調(diào)試操作基于代碼行,隨意性大,函數(shù)內(nèi)代碼是經(jīng)常修改的,必然導致調(diào)試操作重用性差。因此,通過基于函數(shù)調(diào)用接口的檢視操作,函數(shù)原型的穩(wěn)定性相對要高些,可避免調(diào)試生成的腳本過于繁雜,或因源代碼易變導致的可維護性差的問題。
3、引入一種新的調(diào)試工作有效性的評估方法。
該方法能夠適應(yīng)調(diào)試轉(zhuǎn)測試的應(yīng)用場景,以及適應(yīng)第4代白盒測試方法的要求。
根據(jù)本發(fā)明的一個方面,提供了一種程序測試系統(tǒng),所述程序測試系統(tǒng)包括測試主機和目標機,所述測試主機對所述目標機的程序進行調(diào)測,其中,所述目標機中包含調(diào)用轉(zhuǎn)向模塊,所述調(diào)用轉(zhuǎn)向模塊包括轉(zhuǎn)向配置子模塊,用于配置被測試程序的被測函數(shù)完成一次轉(zhuǎn)向所需的配置項,所述配置項設(shè)置在轉(zhuǎn)向控制表中;轉(zhuǎn)向控制子模塊,識別主調(diào)函數(shù)與被調(diào)用函數(shù),根據(jù)轉(zhuǎn)向控制表中的配置項控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);和樁函數(shù)調(diào)用子模塊,根據(jù)轉(zhuǎn)向控制子模塊的當前調(diào)用轉(zhuǎn)向控制,調(diào)用相應(yīng)的測試專用函數(shù)。
根據(jù)本發(fā)明的另一方面,提供一種程序測試方法,包括配置被測試程序的被測函數(shù)完成一次轉(zhuǎn)向所需的配置項;識別主調(diào)函數(shù)與被調(diào)用函數(shù),控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);和根據(jù)轉(zhuǎn)向控制子模塊的當前調(diào)用轉(zhuǎn)向控制,調(diào)用相應(yīng)的測試專用函數(shù)進行測試。
其中,測試專用函數(shù)既包括測試中動態(tài)定義的腳本函數(shù),也包括在被測系統(tǒng)中預先駐留的函數(shù)。
本發(fā)明的優(yōu)點在于采用了一種腳本化的補丁技術(shù),讓測試樁能用腳本來定義,實現(xiàn)測試樁在線定義、在線更新,支持將靜態(tài)測試設(shè)計轉(zhuǎn)化為動態(tài)、在線的模式,因而大幅度提高測試設(shè)計的工作效率。另外,在線測試還帶來“所見即所得”的應(yīng)用模式,對終端用戶更為友好,人機交互方式更加人性化。
軟件調(diào)試過程實現(xiàn)形式化描述后,調(diào)試操作可記錄、可重復,在此基礎(chǔ)上為適應(yīng)程序測試的需要,采用一定規(guī)格與形式將調(diào)試操作轉(zhuǎn)化為檢視描述,形成規(guī)范的測試用例。這使得程序測試真正重用調(diào)試操作,提高了測試腳本的開發(fā)與調(diào)試的效率,并且解決了現(xiàn)有技術(shù)因調(diào)試的隨意性與代碼行的易變性而帶來自動生成用例的可維護性差的問題。
采用上述腳本化補丁技術(shù),還實現(xiàn)一種可定制的,等效于語句覆蓋與分支覆蓋的測試程度評估方法。本方法不僅支持測試工具的快速實現(xiàn),降低開發(fā)成本,可定制的形式也有利于測試過程能按平穩(wěn)質(zhì)量向前推進。
概括而言,本發(fā)明可大幅度提高軟件白盒測試的效率,提高測試操作的易用性,另外還有利于測試質(zhì)量得到保障,這些優(yōu)點已在現(xiàn)有VcTester工具的推行實踐中得到體現(xiàn)。


圖1顯示了根據(jù)本發(fā)明的在被測系統(tǒng)中駐留的調(diào)用轉(zhuǎn)向模塊的結(jié)構(gòu)示意圖;圖2顯示了根據(jù)本發(fā)明的實現(xiàn)函數(shù)調(diào)用轉(zhuǎn)向的原理圖;圖3顯示了根據(jù)本發(fā)明的實現(xiàn)跳轉(zhuǎn)控制前后的調(diào)用關(guān)系;圖4是根據(jù)本發(fā)明一個實施方式的腳本補丁操作流程圖;圖5顯示了根據(jù)本發(fā)明的自擴展調(diào)試器的行號入棧與出棧過程;圖6顯示了本發(fā)明用于實現(xiàn)在線測試系統(tǒng)的框架結(jié)構(gòu);圖7顯示了本發(fā)明中測試代理模塊的層次結(jié)構(gòu);圖8顯示了映射支持模塊的初始化過程;圖9顯示了映射實例的生成過程;圖10示例性地顯示了一個映射實例的TData與TType對應(yīng)關(guān)系;圖11示例性地顯示了根據(jù)本發(fā)明的映射實例的屬性。
具體實施例方式
下面將結(jié)合附圖對本發(fā)明的程序測試系統(tǒng)及方法的實施方式進行詳細的說明。
圖1顯示了根據(jù)本發(fā)明的一個實施方式的在被測系統(tǒng)中駐留的調(diào)用轉(zhuǎn)向模塊10的結(jié)構(gòu)示意圖。該模塊用于在被測函數(shù)調(diào)用時將其調(diào)用改向,使測試專用函數(shù)能替代原有函數(shù)來運行。調(diào)用轉(zhuǎn)向模塊10包括三個子模塊,即轉(zhuǎn)向配置子模塊101、轉(zhuǎn)向控制子模塊102與樁函數(shù)調(diào)用子模塊103,這三者共同地實現(xiàn)了一種在線補丁技術(shù),即在不停機情況下,修改系統(tǒng)中某些函數(shù)的處理過程,以特定的新定義函數(shù)替代原有函數(shù)。這種函數(shù)替換技術(shù)在本發(fā)明中僅用于軟件調(diào)測。
需要說明,函數(shù)替換技術(shù)也就是補丁技術(shù),現(xiàn)有技術(shù)中已提供了一些方法使用補丁技術(shù)用來修正已發(fā)行到市場的軟件BUG。在本發(fā)明中的補丁技術(shù)服務(wù)于市場發(fā)布前的調(diào)測,與現(xiàn)有技術(shù)中補丁技術(shù)的應(yīng)用場合不同。本發(fā)明的補丁技術(shù)與現(xiàn)有技術(shù)中通用的補丁實現(xiàn)方法也不一樣,常規(guī)的補丁技術(shù)通常用jump語句絕對跳轉(zhuǎn),而本發(fā)明是對函數(shù)調(diào)用棧進行處理,通過修改函數(shù)返回值來實現(xiàn)。
其中,轉(zhuǎn)向配置子模塊101用于設(shè)置如下信息1)哪些被測函數(shù)需要轉(zhuǎn)向;2)將要轉(zhuǎn)向至哪個目標函數(shù),即測試專用函數(shù);3)轉(zhuǎn)向控制的狀態(tài)標記,如激活、去激活等。
轉(zhuǎn)向配置是針對一個個的被測函數(shù)進行的。在本發(fā)明中,使用“轉(zhuǎn)向控制塊”(Transfer Control Block,TCB)來描述一個函數(shù)完成一次轉(zhuǎn)向所需的配置項。轉(zhuǎn)向控制表是多個轉(zhuǎn)向控制塊TCB的集合。轉(zhuǎn)向配置子模塊101管理轉(zhuǎn)向控制表。
轉(zhuǎn)向控制子模塊102包含如下功能1)分析主調(diào)函數(shù)(caller)與被調(diào)用函數(shù)(callee);從當前調(diào)用棧遍歷最近各層函數(shù)調(diào)用的返回地址,由返回地址所處范圍結(jié)合轉(zhuǎn)向控制表中信息,分析出當前主調(diào)函數(shù)與被調(diào)函數(shù)。
例如,假定主調(diào)函數(shù)是caller_function,被調(diào)用函數(shù)是callee_function。在callee_function函數(shù)體執(zhí)行前先調(diào)用轉(zhuǎn)向控制函數(shù)pseudo_call,調(diào)用次序為“caller_function->callee_function->pseudo_call”。此處,pseudo_call插在callee_function首部來執(zhí)行,從邏輯上理解,pseudo_call屬于calee_function范圍,但不屬于callee_function的固有函數(shù)定義。在pseudo_call執(zhí)行中遍歷當前調(diào)用棧,可獲知pseudo_call與callee_function調(diào)用后的返回地址。由于pseudo_call函數(shù)是按確定規(guī)則插裝的,所以可根據(jù)pseudo_call的返回地址推算出callee_function的入口地址。根據(jù)這個入口地址查詢“轉(zhuǎn)向控制表”,就可獲得callee_function的轉(zhuǎn)向控制塊(TCB)。另外,根據(jù)callee_function的返回地址查詢轉(zhuǎn)向控制表,一樣可獲得caller_function的TCB。
2)查詢當前調(diào)用棧獲取調(diào)用返回地址;3)控制當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);
4)將測試專用函數(shù)的調(diào)用結(jié)果返回給調(diào)用者;5)記錄調(diào)用覆蓋信息。通過分析出主調(diào)與被調(diào)函數(shù),來記錄“主調(diào)-被調(diào)”函數(shù)對是否被覆蓋。
樁函數(shù)調(diào)用子模塊103主要實現(xiàn)測試專用函數(shù)的調(diào)用。即模擬函數(shù)調(diào)用的方式,先把參數(shù)壓棧,再調(diào)用測試專用函數(shù)。另外還需要先判斷當前樁是否激活,若激活就調(diào)用測試專用函數(shù)(即測試樁)。測試樁包括兩種形態(tài)預駐留函數(shù)與腳本函數(shù),實現(xiàn)調(diào)用都是先把參數(shù)壓棧后調(diào)用函數(shù)地址。測試專用函數(shù)既包括測試中動態(tài)定義的腳本函數(shù),也包括在被測系統(tǒng)中預先駐留的函數(shù)。在測試中,用戶可定義一個腳本函數(shù),再對被測函數(shù)打樁,讓腳本函數(shù)替換被測函數(shù)來執(zhí)行。而且,由于腳本函數(shù)支持在線更新,所以腳本打樁也支持測試樁邏輯在線更新。
為了實現(xiàn)函數(shù)調(diào)用轉(zhuǎn)向,首先在每個被測函數(shù)的首部插入一個轉(zhuǎn)向控制函數(shù)pseudo_call。如圖2所示,當主調(diào)函數(shù)caller_function調(diào)用callee_function時,callee_function中首條語句就是pseudo_call調(diào)用,pseudo_call是圖1中調(diào)用轉(zhuǎn)向模塊的主處理函數(shù),其主要功能是實現(xiàn)調(diào)用控制轉(zhuǎn)向。
轉(zhuǎn)向控制函數(shù)pseudo_call可實現(xiàn)兩類返回跳轉(zhuǎn),其一是替換方式跳轉(zhuǎn),讓測試專用函數(shù)完全替代被調(diào)用函數(shù),如圖2中實線A所標示,callee_function在首行pseudo_call調(diào)用后,立即返回到主調(diào)函數(shù);其二是插入方式跳轉(zhuǎn),如圖2中虛線B標示,pseudo_call執(zhí)行后,被調(diào)函數(shù)的定義體仍被執(zhí)行。在這種情況下,相當于測試專用函數(shù)插在被調(diào)函數(shù)之前運行了。這兩類返回跳轉(zhuǎn)所實現(xiàn)的腳本樁分別叫替換模式測試樁與插入模式測試樁。
為實現(xiàn)轉(zhuǎn)向控制,需要解決以下問題。
1.轉(zhuǎn)向控制函數(shù)的插裝把pseudo_call函數(shù)插入被測函數(shù)的首部,可采取四種方式1)借助編譯器提供的插裝功能。
某些編譯器支持在函數(shù)調(diào)用前插入特定樁函數(shù),例如Visual C/C++系列版本支持penter樁插入,使用編譯開關(guān)“/Gh”可做到這一點。
2)借助符號跳轉(zhuǎn)表實現(xiàn)自動插裝某些編程語言的函數(shù)調(diào)用,是通過符號跳轉(zhuǎn)表實現(xiàn)的,比如在GCC中,調(diào)用某函數(shù),實際是調(diào)用它在符號跳轉(zhuǎn)表的某地址,該地址再使用一個jmp絕對跳轉(zhuǎn)語句才跳轉(zhuǎn)到真正函數(shù)定義的位置。通過修改符號跳轉(zhuǎn)表即可插入pseudo_call函數(shù)調(diào)用。
3)借助逗號表達式實現(xiàn)插裝例如在C語言中,已知某符號是函數(shù),可以按以下方式插裝#define printf(pseudo_call(),printf)使用逗號可連接多個表達式,運算時返回最后一個表達式的值。上例對printf函數(shù)做插裝,“printf”被替換成“(pseudo_call(),printf)”,由于逗號運算的特點,語句“printf(“example”)”等效于“(pseudo_call(),printf)(“example”)”,“ptr=&printf”等效于“ptr=&(pseudo_call(),printf)”。
這種借助逗號表達式與宏替換的插裝,既可以手工實現(xiàn),也可以由調(diào)測工具自動實現(xiàn)。如本處舉例的printf宏替換語句可由工具自動生成,只要確定某符號是函數(shù)類型,不需知道它的原型就能實現(xiàn)插裝。
4)手工插裝也可以通過手工方式在被測函數(shù)首部插入pseudo_call函數(shù)。若為方便起見,定義一個宏指向pseudo_call調(diào)用,關(guān)閉這個宏(即取消該宏定義(undefine),對應(yīng)C語言的“#undef”指令)即取消插裝。例如在C語言中定義如下宏#define begin {pseudo_call();define end}在編碼時,需要一律以begin作為函數(shù)定義開始,以end作為函數(shù)定義結(jié)束。
以上四種方式中,第二種可以是動態(tài)、在線方式把pseudo_call函數(shù)插入,其它幾種方式是靜態(tài)的,在被測可執(zhí)行程序生成之前就插入了。
2.轉(zhuǎn)向控制為實施測試,需要將特定的子函數(shù)調(diào)用轉(zhuǎn)向到測試專用函數(shù)(即測試樁),為此需要執(zhí)行轉(zhuǎn)向控制。
以C語言調(diào)用棧的組織特點為例。可以修改當前調(diào)用棧內(nèi)的返回地址就實現(xiàn)轉(zhuǎn)向控制。例如函數(shù)A主調(diào)函數(shù)B時,先將主調(diào)函數(shù)B后要返回的地址壓棧,然后進入B函數(shù)執(zhí)行。當B函數(shù)尚在運行中,如果把剛壓棧的返回地址改成另一函數(shù)C的地址值,那么,函數(shù)B運行結(jié)束就不會返回到函數(shù)A,而是轉(zhuǎn)向到函數(shù)C。
圖2中caller_function調(diào)用callee_function,callee_function先調(diào)用pseudo_call,這兩次調(diào)用都先將返回地址壓棧。如圖3所示,在調(diào)用callee_function時(步驟302),先將callee_function的返回地址RetAddr_of_callee壓棧(步驟301)。而在調(diào)用pseudo_call時(步驟304),先將pseudo_call的返回地址RetAddr_of_Pseudo壓棧(步驟303)。在pseudo_call執(zhí)行過程中,如果將調(diào)用棧中pseudo_call返回地址改為callee_function的返回地址,就導致callee_function定義體不被執(zhí)行,相當于插入運行的pseudo_call函數(shù)替代callee_function運行了,這就是替換模式樁。
如果不修改棧中的返回地址,pseudo_call插在callee_function定義體之前運行,就是上文所述的插入模式樁。
3.查找轉(zhuǎn)向控制塊轉(zhuǎn)向控制表用于按地址值索引被測函數(shù)的轉(zhuǎn)向控制塊(TCB),索引可以有兩類地址值,一是被測函數(shù)的入口地址,二是被測函數(shù)調(diào)用子函數(shù)時的返回地址。TCB中記錄的函數(shù)名稱、函數(shù)原型、函數(shù)所在源文件及行號、是否存在補丁函數(shù)、補丁函數(shù)類型(腳本/預駐留/未知)、補丁是否激活等信息,這些信息以及它對應(yīng)函數(shù)的地址范圍可從以下渠道獲得1)從編譯器生成的調(diào)試數(shù)據(jù)庫中獲取,如VC的PDB文件,GCC的GDB信息記錄;2)從編譯過程文件中提取,如C語言的OBJ文件、Delphi語言的DCU文件等;3)從編程語言開發(fā)商提供的dump工具獲得。
由于打補丁了的被測函數(shù)經(jīng)常在多線程環(huán)境下調(diào)用,這要求本發(fā)明的補丁機制要支持多線程環(huán)境,上面描述的TCB查表過程應(yīng)采用某種互斥機制來保護操作安全。實現(xiàn)時主要保證TCB查表是多線程下安全的,即TCB內(nèi)容可動態(tài)變化。如果要增刪補丁,或修改補丁的狀態(tài),就得修改相應(yīng)TCB內(nèi)容,稱為TCB狀態(tài)維護。轉(zhuǎn)向操作過程中要獲取并使用相應(yīng)的TCB,其過程要與TCB狀態(tài)維護操作互斥。該互斥按常規(guī)的方法實現(xiàn)即可。
下面將參考圖4描述在根據(jù)本發(fā)明的一個實施方式中對一個被測函數(shù)啟用腳本補丁、實現(xiàn)調(diào)用轉(zhuǎn)向,以及調(diào)用結(jié)束后關(guān)閉補丁的操作過程。
圖4左側(cè)4個步驟是概要處理過程,右側(cè)是概要步驟的第3步“發(fā)起測試”的分解過程。
在步驟401,針對被測函數(shù)設(shè)置腳本形式的補丁函數(shù),即填寫相應(yīng)TCB表,表中記錄某函數(shù)對應(yīng)某補丁。接著激活該腳本補丁(步驟402)。在腳本補丁被激活后,就可以發(fā)起測試,(即運行被測函數(shù),步驟403)。
在步驟403中,首先,進入被測的主調(diào)函數(shù)caller(步驟4031),主調(diào)函數(shù)caller調(diào)用被調(diào)用函數(shù)callee(步驟4032)。之后,進入轉(zhuǎn)向控制函數(shù)pseudo_call(步驟4033),分析出主調(diào)函數(shù)與被調(diào)用函數(shù)(步驟4034)。
接下來,判斷是否已定義了腳本補丁且該腳本補丁被激活(步驟4035)。如果是,則設(shè)置調(diào)用返回的轉(zhuǎn)向地址(步驟4036),然后調(diào)用腳本函數(shù),并傳遞腳本調(diào)用的返回值(步驟4037)。否則,從pseudo_call直接返回(步驟4038),完成callee函數(shù)調(diào)用,并傳遞該函數(shù)返回值(步驟4039)。
在步驟4036或4039傳遞了調(diào)用返回值后,返回到caller函數(shù)繼續(xù)執(zhí)行(步驟4040),完成被測函數(shù)caller調(diào)用。
最后,刪除或去激活該腳本補丁(步驟404)。
圖4操作流程是針對補丁函數(shù)是腳本函數(shù)的情況,如果補丁函數(shù)是被測系統(tǒng)中的預先駐留的函數(shù)時,整體流程類似,僅有如下差別1)設(shè)置補丁函數(shù)時指向預駐留函數(shù),而不是腳本函數(shù);2)判斷補丁是否激活之后運行補丁函數(shù)時,是調(diào)用預駐留函數(shù),而不是腳本函數(shù)。
4.自擴展調(diào)試器在轉(zhuǎn)向控制函數(shù)pseudo_call執(zhí)行中,可識別主調(diào)用caller函數(shù)與被調(diào)callee函數(shù)。利用此特性,本發(fā)明可在pseudo_call函數(shù)構(gòu)造支持單步跟蹤的調(diào)試機制,本發(fā)明要求這個自擴展的調(diào)試器基本等效于常規(guī)開發(fā)語言的單步跟蹤機制,即提供諸如設(shè)置斷點、單步跟蹤、查看變量、修改變量等主要調(diào)試功能。
自擴展調(diào)試機制在用戶應(yīng)用代碼層次實現(xiàn)。該機制不依賴于常規(guī)調(diào)試器所采用的中斷方式實現(xiàn)。所以,本調(diào)試器與編程語言自帶調(diào)試器是可兼容并存的,兩者能同時使用。而且,兩者可以隨時、在線進行切換,切換不必重起被測系統(tǒng)。不必重啟被測系統(tǒng)是因為兩者機理上不沖突,上述自擴展調(diào)試器實際等效于用戶自己寫的程序(其操作界面在使用時象調(diào)試器),它的工作原理與編譯器自帶的調(diào)試器不沖突。這一點在測試工具實施時比較有利,因為編譯器自帶的調(diào)試器功能更為全面(比如能看匯編代碼、能讀寫寄存器等),本發(fā)明的自行擴展的調(diào)試器就不需面面俱到地實現(xiàn)編譯器自帶的每一項功能,采用在線切換可降低自擴展調(diào)試器因功能不足而帶來的負面影響。
具體而言,在執(zhí)行每個被測函數(shù)首部的pseudo_call函數(shù)時,先分析出主調(diào)函數(shù)與被調(diào)用函數(shù),從被調(diào)函數(shù)的TCB中獲得當前函數(shù)所在的源文件與行號,此時若當前處于斷點狀態(tài),pseudo_call將等待用戶輸入下一步跟蹤指令,比如函數(shù)內(nèi)單步(Step)、跟入下一級函數(shù)(StepIn)、跟出當前函數(shù)(StepOut)等、繼續(xù)執(zhí)行直到下一斷點(Run),pseudo_call根據(jù)不同指令對行號棧做不同操作。
在本發(fā)明中,設(shè)計一個“行號棧”來保存單步跟蹤中歷史行號的位置,以便函數(shù)單步跟出時,能準確識別上級函數(shù),并能跳回到歷史跟入的位置。例如,在函數(shù)1調(diào)用函數(shù)2、函數(shù)2中又調(diào)用函數(shù)3時,針對行號信息的壓棧與出棧過程如圖5所示。其中,出棧過程表示函數(shù)3調(diào)用結(jié)束并返回至函數(shù)2、函數(shù)2調(diào)用結(jié)束并返回至函數(shù)1、直至函數(shù)1結(jié)束操作返回上一級函數(shù)時的行號棧的變化過程。本領(lǐng)域技術(shù)人員可以理解,所述棧是典型的先入后出的數(shù)據(jù)結(jié)構(gòu)。
如果跟蹤指令是“繼續(xù)執(zhí)行到下一斷點”,也由執(zhí)行路徑上各函數(shù)的pseudo_call函數(shù)識別出當前函數(shù)有無斷點,若有斷點再分析斷點條件是否滿足,若斷點條件滿足就自動進入交互式單步狀態(tài)。
本發(fā)明的自擴展調(diào)試器還可支持在斷點調(diào)試中用測試腳本存取被測系統(tǒng)中的變量,包括全局變量與局部變量,以及用腳本發(fā)起被測函數(shù)調(diào)用。腳本化的變量存取與函數(shù)調(diào)用可采用一種語言映射技術(shù)實現(xiàn)。下面將具體說明這種映射。
圖6顯示了腳本解釋器驅(qū)動的實現(xiàn)在線測試系統(tǒng)的框架結(jié)構(gòu)。如圖所示,測試主機1包含測試外殼(Test Shell)11,用于發(fā)起調(diào)測命令,以及提供開發(fā)、測試的平臺。測試主機端可以采用個人桌面系統(tǒng)(如Windows、Linux等)。測試外殼11可以是其中的一個可執(zhí)行程序。
目標機2(即被測系統(tǒng))通常是被測單板,或者是一個仿真程序。目標機2中駐留有測試代理(Test Agent)模塊21。該測試代理模塊21可以是一個腳本語言系統(tǒng)。在本發(fā)明中,對腳本語言的種類并沒有限定,只要能滿足本發(fā)明規(guī)定的映射規(guī)則即可。在目標機2的測試代理模塊21內(nèi)包含有被測試程序的符號表和類型表。關(guān)于符號表和類型表將在后文中說明。
測試主機1的測試外殼11與測試代理模塊21具有通信連接。此連接的通信方式可以是共享內(nèi)存通信(對于目標機與測試主機共用同一臺計算機的情況、TCP/IP通信,或是其它如串口通信等形式。
如圖7所示,測試代理模塊21包括腳本系統(tǒng)211和通訊單元212。通訊單元212負責處理測試代理模塊21與測試主機1的測試外殼11的上述通信連接。
腳本系統(tǒng)211包括內(nèi)嵌調(diào)測支持模塊2111和映射支持模塊2112。內(nèi)嵌調(diào)測支持模塊2111是常規(guī)的調(diào)測應(yīng)用編程接口(API)的集合,提供諸如復位目標機、啟動或停止某任務(wù)、設(shè)置斷點、刪除斷點等功能。映射支持模塊2112用于實現(xiàn)被測系統(tǒng)中的C語言變量與函數(shù)向腳本系統(tǒng)映射的功能。在完成映射后,腳本系統(tǒng)211中生成與C語言的變量和函數(shù)同名的映射變量與映射函數(shù)。
為了實現(xiàn)本發(fā)明的目的,要求測試主機1和目標機2都應(yīng)該有對腳本文件的處理能力。為此,測試主機1的測試外殼11中包含了一個命令行編輯輸入單元以及命令解釋模塊(未示出),命令行編輯輸入單元用于支持用戶輸入腳本文件格式的調(diào)測命令,命令解釋模塊把輸入的調(diào)測命令轉(zhuǎn)化為能夠由測試代理模塊21中的腳本解釋器解釋執(zhí)行的測試命令,并傳送給目標機2的測試代理模塊21。測試代理模塊21中相應(yīng)地包含一個腳本解釋器(未圖示),用于實現(xiàn)測試控制。腳本解釋器接收命令解釋模塊傳送來的測試命令,對該命令進行解釋并實施相應(yīng)動作。實際傳遞的格式是中間碼格式,類似Java虛擬機解釋字節(jié)碼命令一樣,這個中間碼格式也稱偽編譯碼。
當目標機2執(zhí)行測試并反饋結(jié)果、或在測試過程中發(fā)出了打印信息,測試主機1的測試外殼11將會接收該結(jié)果或信息并進行處理。
參見圖8,首先,目標機2要進行初始化處理。當測試主機1啟動命令解釋模塊的程序時,目標機2啟動被測程序(S501)。然后,目標機2初始化其中包含的腳本系統(tǒng)211,包括設(shè)置測試代理模塊21的相關(guān)配置(S502)。在此過程中,測試代理模塊21的表生成單元(未示出)從目標機2被測試的軟件在其最后一次編譯后生成的GDB或PDB調(diào)試數(shù)據(jù)庫中提取與被映射的變量/函數(shù)相關(guān)的信息,生成符號表和類型表(后文將要說明),并記錄在測試代理模塊21中(S503)。然后,測試代理模塊21的腳本系統(tǒng)211把符號表及類型表映射到一個全局的變量容器(S504)。按照預定的腳本把類型表、符號表的符號都映射至變量容器中(S505)。該操作將被測程序中的變量與函數(shù)在腳本系統(tǒng)中描述為映射對象(即腳本的TData類對象)。由于轉(zhuǎn)換全部符號會導致CPU與內(nèi)存資源浪費,因此根據(jù)本發(fā)明的一個實施方式,不對符號作一次性全部轉(zhuǎn)換,而僅根據(jù)測試需要來映射。例如,運行測試腳本時,腳本包含哪些映射的變量與函數(shù),就動態(tài)轉(zhuǎn)換那些變量或函數(shù),或者由用戶自行確定規(guī)則來按需轉(zhuǎn)換,比如所有外部定義的符號都不作映射。
此后,進行被測系統(tǒng)的正常測試(S506)。在測試主機1,用戶使用類似C語言的腳本文件對傳送來的編碼進行操作。測試外殼11中的命令解釋模塊解釋用戶的輸入,并發(fā)出相應(yīng)的測試指令。該命令被傳送到測試目標機2,并在其腳本系統(tǒng)211中運行,從而得到按編碼邏輯所得到的測試運行結(jié)果。這個測試運行結(jié)果可被反饋到測試主機1,并顯示給用戶。在上述方法中,由于可以在線地編寫測試腳本,直觀地查看或修改被測變量、調(diào)用被測函數(shù),所見即所得,可以馬上看到測試結(jié)果,也可馬上改進測試,從而提高了測試的效率。
因為C語言編碼對其數(shù)據(jù)的結(jié)構(gòu)/類型要求很嚴格,作為它的映射后的腳本,必須能夠支持基本的C編程的功能和要求。
為了實現(xiàn)上述對C語言編碼的映射,根據(jù)本發(fā)明,在目標機2的測試代理模塊21中駐留了被測試程序的符號表和數(shù)據(jù)類型表。這兩個表將直接支持本發(fā)明規(guī)定的映射規(guī)則的實現(xiàn)。本發(fā)明的映射方法依賴于對目標機系統(tǒng)的各種符號及其類型信息的收集與分析。調(diào)試數(shù)據(jù)庫在編譯過程中由編譯器產(chǎn)生,例如Visual C/C++編譯過程中會產(chǎn)生PDB文件,GCC在編譯時也將GDB調(diào)試信息編譯到目標程序中。如上所述,這些信息可在編譯過程中由編譯器產(chǎn)生的調(diào)試數(shù)據(jù)庫中提取,根據(jù)所提取的信息相應(yīng)生成符號表和類型表。
不同的C編譯器生成的調(diào)試數(shù)據(jù)庫格式并不一樣。本發(fā)明通過對類型表和符號表的生成達到了對不同格式的統(tǒng)一。類型表記錄被測系統(tǒng)定義過的各種類型。這些類型必須包括主類型信息、子類型信息、以及占用字節(jié)數(shù)。表1是類型定義格式的示例表1


同時要確保類型表下各欄目具有唯一性,即,由相同的主類型與子類型以及占相同字節(jié)數(shù)而構(gòu)成的類型項只能存在一個。
符號表記錄變量或函數(shù)的地址值及其類型ID。其中符號地址有兩種形式,既可以記錄絕對地址,也可以記錄相對地址。例如,存取函數(shù)內(nèi)局部變量或傳入?yún)?shù)時,則使用相對于當前棧頂位置的偏移值。再如,某變量在另一變量空間下存在,其地址也按該另一變量的地址加上一個偏移來表達。
符號來源有兩種方式,一是來源于另一映射對象,二是來源于某絕對地址。后者是描述變量或函數(shù)的常規(guī)方式,前者常在將同一內(nèi)存空間看作多種類型的變量進行操作時使用,例如強制類型轉(zhuǎn)換,是將某字串數(shù)組的某一偏移看成整數(shù)類型變量。
在生成了符號表和類型表之后,為了腳本的操作方便,系統(tǒng)要定義與表中數(shù)據(jù)相應(yīng)的轉(zhuǎn)化腳本類對象,即TType類對象對應(yīng)于類型表,TData類對象對應(yīng)于符號表。在TType類對象定義的實例化數(shù)據(jù)要包含如下信息該類型唯一的標識,類型主類別信息,類型子類別信息,類型大小。各個符號映射為TData類定義的實例化數(shù)據(jù),要包含以下信息該符號對應(yīng)的類型ID,符號的來源,相對于來源的偏址,是否是自動釋放內(nèi)存。
表格內(nèi)容的映射按圖6進行。首先,腳本系統(tǒng)211從符號表里找出需要的符號(包括變量和函數(shù))信息,如符號名稱,符號的類型ID及符號地址(步驟901)。然后腳本系統(tǒng)211通過該類型ID查找相應(yīng)的類型是否有生成的TType類對象,若沒有則創(chuàng)建該TType類對象,即通過定義TData或TType類對象,調(diào)用類定義的建構(gòu)函數(shù)來創(chuàng)建這個類對象的實例(步驟902)。最后,根據(jù)該符號的來源、所屬的TType對象、地址偏移及是否自動釋放內(nèi)存等信息創(chuàng)建被映射符號的TData類對象(步驟903)。
在創(chuàng)建的映射實例包括映射變量與映射函數(shù)時,首先要有相應(yīng)的TType對象指明類型信息。當類型表中的各項都轉(zhuǎn)化成TType類實例后,原有類型信息表不再有用,其占用的資源可釋放,而用新生成的各個TType類實例組成一個新表,即TType類型表。映射變量與映射函數(shù)都是TData類實例。如圖7所示,每個TData類實例使用該符號對應(yīng)的類型ID(Data type)指示它使用TType類型表中的哪個類型。
需要注意,TType類的對象可能是嵌套引用的。某些復合類型如struct/union/指針等包含了子類型,而且同一子類型可能被多個復合類型引用。所以,在創(chuàng)建每個TType對象時,該類型涉及的其它類型也同時被創(chuàng)建。
由于測試主機和目標機的系統(tǒng)資源是有限的,為了更有效地進行測試,在相應(yīng)時期對使用資源的處理是十分重要的。根據(jù)本發(fā)明,為了有效利用系統(tǒng)資源,變量、函數(shù)、類對象等在腳本語言中作為一個實體存在,實現(xiàn)了生存周期自動管理。這些實體所占用的資源會自動申請、自動釋放。映射數(shù)據(jù)作為腳本類對象,也支持它所涉及資源的自動申請與釋放。
例如,腳本系統(tǒng)21要創(chuàng)建一個映射變量buff,它是一個長度為24字節(jié)的字串數(shù)組,這時腳本系統(tǒng)21會向目標機2自動申請它占用的內(nèi)存,包括buff變量作為腳本TData類實例要占用的內(nèi)存空間,以及字串數(shù)組的24字節(jié)空間。為描述方便,在本發(fā)明中,將前一類空間稱為腳本實例空間,將后一類空間稱為C實例空間。當新創(chuàng)建的映射變量的生存周期結(jié)束時,這兩種空間都將被自動釋放。
但是,由于編程的復雜性,腳本實例空間與C實例空間并不總是同時申請或同時釋放的。例如對于被測系統(tǒng)的全局變量,其占用空間是靜態(tài)分配的,全局變量的映射實例在生存周期結(jié)束時,應(yīng)只釋放腳本實例空間,而不應(yīng)釋放C實例空間。再如,使用腳本文件中創(chuàng)建一個映射變量a后,這個變量的腳本實例空間與C實例空間應(yīng)同時申請或釋放。但是,如果把這個映射變量a看成另一類型的映射變量b,例如C語言中的強制類型轉(zhuǎn)換時,將同一地址空間下某變量,看成另一類型的變量,則創(chuàng)建變量b時應(yīng)新申請腳本實例空間,但不應(yīng)重復申請C實例空間。另外,當變量a或變量b被刪除時,不管先刪除哪一個,都應(yīng)保證尚在使用的另一個變量所操作的C實例空間還有效。也即C實例空間可被多個映射變量共享,只有該C實例空間所全部涉及的映射變量都釋放了,這個C實例空間才自動被釋放。此外,映射變量使用的C實例空間還需配合測試,必要情況下可修改其中的標志。例如為映射變量設(shè)置Autofree屬性,該屬性為TRUE表示該映射變量的C實例空間是隨它的腳本實例空間釋放而釋放的,否則屬性取值為FALSE,表示C實例空間不隨腳本實例空間釋放而釋放。
為實現(xiàn)上述目的,根據(jù)本發(fā)明的一個實施方式,對映射實例設(shè)置了3個屬性。圖8顯示了映射實例的一個示例。如圖8所示,該屬性包括是否自動釋放內(nèi)存(Autofree)、符號來源(Owner)、相對于來源的偏移地址(Offset)。其中“是否自動釋放內(nèi)存”的屬性用于指示該映射變量的C實例空間是否跟隨腳本實例空間一起釋放?!胺杹碓础庇糜谥甘驹撚成鋵嵗臍w屬對象,其取值既可以是某絕對地址值,也可以是另一個映射實例。相對于來源的偏移地址用于指示本映射實例所用C實例空間的起始地址相對于其符號來源指示的空間地址的偏移量是多少。由于腳本語言具備生存周期自動管理特性,所以如果使符號來源屬性指示另一映射實例,就實現(xiàn)了同一C實例空間被多個映射實例共用時也能夠?qū)崿F(xiàn)資源的自動管理。
在這些初始階段的步驟完成后,系統(tǒng)還要生成一個全局的變量容器。該全局變量容器用于包含所有的變量和函數(shù),并將它們置于統(tǒng)一的平臺下。變量容器能捕獲針對該實例的屬性取值與賦值的操作,并根據(jù)特定情況進行操作轉(zhuǎn)義。容器本質(zhì)上也是腳本的類對象,只不過存取它的屬性時,系統(tǒng)會做特定的截獲處理。
例如,參考下式定義的變量容器vc=newVarContainer();vc.Var3=MapString(“Another string”);vc.Var3=“Change value”;vc.Var4=MapString(“It is example!”);vc.Var4=vc.Var3;在這個例子中,第3行和最后一行分別是針對Var3的賦值和取值,最后一行是按照C語言風格描述的。為實現(xiàn)這一點,變量容器下的映射變量的取值和賦值將進行轉(zhuǎn)義,如下兩條語句vc.Var3=“Change value”;vc.Var4=vc.Var3;等同于vc.Var3.setValue(“Change value”);vc.Var4.setValue(vc.Var3.getValue());可以看到,vc.Var3=“Change value”是合乎C風格的賦值,而vc.Var3.setValue(“Change value”)是調(diào)用,不是賦值,遠離C風格了。
為支持轉(zhuǎn)義,腳本語言本身的類方法操作要支持定向功能,定向后使用賦值語句最終執(zhí)行這個調(diào)用語句(vc.Var3.setValue(“Change value”))。
變量容器除支持以上取值與賦值轉(zhuǎn)義外,還要支持按腳本方式的變量賦值,即用指定的值代替變量原有值,而不管原有值是不是映射變量。例如vc.Var4=MapString(”It is example!”);setVcValue(vc,“Var4”,“Another string”);在這個例子中,第一條語句在變量容器下創(chuàng)建字串映射變量Var4,第二條語句將這個Var4替換成腳本的字串值。該句執(zhí)行后,Var4不再是映射變量了,而是像常規(guī)腳本變量那樣賦值,其類型是動態(tài)變化的。為此,本發(fā)明要求提供用于動態(tài)賦值的API函數(shù)(類似于本例的setVcValue)。
變量容器的使用對于函數(shù)的調(diào)用也是重要的。例如,要實現(xiàn)cdecl與stdcall調(diào)用,在TData類中定義添加callCdecl與callStdcall兩個方法,在腳本中按如下方式調(diào)用C函數(shù)vc.result1=vc.func1.callCdecl(IntType,3,“example”);vc.result2=vc.func2.callStdcall(CharType,‘A’,‘B’);這兩個方法都要求用第一個參數(shù)指明該調(diào)用的返回值類型,其它參數(shù)依次是完成本次C調(diào)用的各參數(shù)值。由這兩個方法發(fā)起調(diào)用沒有基于一種函數(shù)原型,使用有點麻煩,因為調(diào)用時要指定返回值類型,而且各傳入?yún)?shù)的類型是否匹配、參數(shù)個數(shù)是否正確都無法檢查。為改進這一點,在本發(fā)明中對TData添加了對_call_調(diào)用的支持,其使用方法如下vc.result1=vc.func1._call_(3,“example”);
vc.result2=vc.func2._call_(‘A’,‘B’);為了讓描述方法更簡單,本發(fā)明定義腳本類的支持內(nèi)嵌call轉(zhuǎn)向功能,從而把上面的腳本改寫成如下方式vc.result1=vc.func1(3,“example”);vc.result2=vc.func2(‘A’,‘B’);改寫后執(zhí)行效果是等同的,即當類對象自身作為函數(shù)去調(diào)用時,系統(tǒng)自動將它轉(zhuǎn)向到該對象的_call_方法。一些現(xiàn)有的腳本語言,如Python與CSE可支持這種轉(zhuǎn)向。本發(fā)明借助該機制實現(xiàn)新的應(yīng)用,即,讓映射函數(shù)(是腳本實例)調(diào)用與C語言在表達上保持一致,如vc.func._call_(3,“example”)未保持一致,而vc.func(3,“example”)是一致的。至此,使用腳本調(diào)用C函數(shù)的風格就與C語言風格一致了。
除了上述常規(guī)的cdecl與stdcall固定參數(shù)類型的調(diào)用,本發(fā)明還需要支持cdecl風格的變長參數(shù)調(diào)用,例如變長參數(shù)函數(shù)MyPrint的原型為“void MyPrint(char*format,…)”,根據(jù)本發(fā)明,可以按如下方式調(diào)用它vc.result=vc.MyPrint.callCdecl(“name%s”,“george”);在此,變長參數(shù)調(diào)用要在C函數(shù)調(diào)用發(fā)起前,按參數(shù)傳入值組裝成壓棧數(shù)據(jù)。然后模擬C語言調(diào)用,獲取模擬調(diào)用的返回值。
如果映射函數(shù)有返回值,則調(diào)用映射函數(shù)應(yīng)返回一個映射變量。即原C函數(shù)的返回類型不為void時,取它的類型及返回的數(shù)值,生成映射變量。
在本發(fā)明中,調(diào)試操作中修改被測變量、與調(diào)用被測函數(shù),可以通過上述調(diào)測系統(tǒng)中的語言映射技術(shù)實現(xiàn)。
另外,借助上述語言映射技術(shù)還可實現(xiàn)模擬被測代碼的功能,即,腳本化地存取被測變量與調(diào)用被測函數(shù)。該功能在自擴展調(diào)試器中用于設(shè)置條件斷點,用一個腳本表達式描述斷點條件,只有條件滿足程序才會在斷點位置停住。
由于本調(diào)試機制依賴于在函數(shù)首部插入pseudo_call,必然導致單步跟蹤只在函數(shù)調(diào)用的時候才起作用,無函數(shù)調(diào)用的語句,比如C語言的if、while、switch等控制語句的位置無法在單步跟蹤時停住。針對這一情況,根據(jù)本發(fā)明,把這些非函數(shù)調(diào)用的語句轉(zhuǎn)化成函數(shù)調(diào)用,通常使用逗號表達式的插裝方式做轉(zhuǎn)化,如下#define if(expr) if(pseudo_call(),expr)#define while(expr)while(pseudo_call(),expr)這樣,由于被測函數(shù)的所有控制語句(比如C語言中的if、else、while、for、switch等)與函數(shù)調(diào)用都支持單步跟蹤,并且全局變量與各函數(shù)的局部變量都可讀寫、被測函數(shù)可調(diào)用,因而自擴展調(diào)試器的功能就比較完整,而且,也實現(xiàn)了調(diào)試過程的腳本化控制。
5.將調(diào)試過程轉(zhuǎn)換成腳本描述調(diào)試過程比較隨意,如果把每一個單步跟蹤過程都轉(zhuǎn)化為測試腳本,必然導致自動生成的用例可維護性很差,為解決這個問題,本發(fā)明遵循第4代白盒測試方法的相關(guān)要求,實施灰盒方式測試。
灰盒方式是把被測對象(即被測函數(shù))作為一個整體,測試針對它的外在接口,即被測函數(shù)的傳入?yún)?shù)、返回值,以及該被測函數(shù)涉及的全局變量。該灰盒方式是一種粗粒度調(diào)試,基于函數(shù)接口而非函數(shù)實現(xiàn)過程,保證測試描述既不過于瑣碎,也相對穩(wěn)定,不必每次代碼修改就要調(diào)整用例。
前文敘述的調(diào)試過程實現(xiàn)了腳本化描述,現(xiàn)在為了將這種描述轉(zhuǎn)化成規(guī)范用例,還需要取其子集,只將粗粒度的、基于接口的操作轉(zhuǎn)化成測試腳本。在本發(fā)明中,將能轉(zhuǎn)化成自動用例的調(diào)試操作稱為檢視操作。檢視屬于調(diào)試的子集。
檢視操作(灰盒測試)包括如下步驟1.通過查看或修改全局變量,或調(diào)用被測系統(tǒng)中的函數(shù)來構(gòu)造測試運行環(huán)境;2.調(diào)用被測函數(shù)發(fā)起測試;3.在被測函數(shù)的首部設(shè)置斷點,可指定斷點條件,單步跟蹤到該位置時,可用測試腳本查看與修改傳入的參數(shù)與全局變量。其它被測函數(shù)也可以用測試腳本發(fā)起調(diào)用;4.單步跟蹤時可以在函數(shù)尾部停住。此時,函數(shù)返回值與全局變量可以用腳本查看與修改,其它被測函數(shù)也可以用測試腳本發(fā)起調(diào)用。
將檢視記錄轉(zhuǎn)化為測試腳本(用例)時,應(yīng)滿足以下要求1.在一次調(diào)試的任意檢視操作步驟中,可使用斷言(如assert語句)判斷運行情況是否與期望值相符。在本發(fā)明中,其操作過程能夠被記錄下來的調(diào)試被稱為“檢視”。檢視操作類似于調(diào)試操作,可以象調(diào)試一樣進行單步跟蹤,單步跟蹤過程中可運行斷言語句,例如assert(AValue==BValue),這種斷言直接服務(wù)于測試。
2.調(diào)試中在用戶操作界面可查看當前范圍的各個變量取值,支持選中某些變量,自動按當前取值生成測試斷言。用戶可以觀察當前各個全局變量的取值,如果希望把某幾個變量的取值自動生成結(jié)果進行判斷,選中這幾個變量后再在界面按某個快捷鍵,即能夠自動生成結(jié)果判斷語句,比如assert(AValue==5)。
3.當運行斷點處于函數(shù)的首部與尾部時,用戶在操作界面可選擇是否將調(diào)試操作記錄為測試腳本,即用戶可自行決定某些調(diào)試操作(如查看變量、修改變量、調(diào)用函數(shù))生成到自動用例中,而另一些不必納入到自動用例中。例如當前檢視在函數(shù)首部停住,如果這個函數(shù)傳入?yún)?shù)iValue取值為5,則可以在變量查看列表中選中這個變量,之后在檢視操作結(jié)果后可自動生成相應(yīng)的assert語句,例如assert(iValue==5)。
4.一次調(diào)試后生成的測試用例腳本,還可以按手工方式進行調(diào)整。調(diào)整內(nèi)容可包括用戶可以手工修改這種自動生成的腳本,如上例“assert(iValue==5)”,用戶可把它改為“assert(iValue==6)”。
6.測試程度評估在轉(zhuǎn)向控制函數(shù)pseudo_call中能分析出被測系統(tǒng)中每次調(diào)用的主調(diào)函數(shù)與被調(diào)用函數(shù),依據(jù)這個特性,可以通過分析測試用例對函數(shù)中調(diào)用的覆蓋程度來評估對每個函數(shù)的測試程度。
例如,被測函數(shù)共有10項子函數(shù)調(diào)用,如果測試只覆蓋了一、兩項調(diào)用,說明設(shè)計的測試用例是不夠的。如果10項中有9項或全部調(diào)用都被覆蓋到了,則說明當前測試很充分了。
在pseudo_call函數(shù)中增加調(diào)用信息記錄,就可實現(xiàn)一種調(diào)用覆蓋率統(tǒng)計,即統(tǒng)計測試中已覆蓋到的調(diào)用個數(shù)占被測試函數(shù)總調(diào)用個數(shù)的比例。調(diào)用覆蓋率實際等效于通常白盒測試工具所支持的語句覆蓋。
通過將問號表達式與宏替換組合,可以進一步實現(xiàn)分支覆蓋統(tǒng)計。例如在C語言中定義如下宏#define if(expr) if(expr)?if_1()if_0())#define while(expr)while((expr)?while_1()while_0())在if判斷中,如果判斷條件為TRUE,則執(zhí)行插裝函數(shù)if_1,反之執(zhí)行if_0。在while循環(huán)判斷中,如果判斷條件為TRUE,則執(zhí)行插裝函數(shù)while_1,反之執(zhí)行while_0。這兩種情況實現(xiàn)了C語言的if與while的分支記錄,其它分支語句處理過程類似。在其它編程語言中,借助and與or的短路判斷也能實現(xiàn)類似的分支插裝。
基于調(diào)用的覆蓋率評估還可以支持客戶化的評估定制。在某些情況下,特定的函數(shù)調(diào)用(例如出錯處理函數(shù)、非測試關(guān)注函數(shù)等)不影響測試程度評估,可以將這些特定函數(shù)登記到忽略函數(shù)表中。在pseudo_call執(zhí)行中分析出被調(diào)函數(shù)后,查詢忽略函數(shù)表判斷該被調(diào)函數(shù)是否該被忽略。若忽略就不納入覆蓋率統(tǒng)計。這種可定制的評估機制,可保障軟件研發(fā)過程能持續(xù)、平穩(wěn)地以可控的質(zhì)量向前推進。
本發(fā)明適用于軟件開發(fā)領(lǐng)域,主要針對C語言(但不限于C語言)開發(fā)環(huán)境的軟件調(diào)試與測試。
權(quán)利要求
1.程序調(diào)測系統(tǒng),包括測試主機和目標機,所述測試主機對所述目標機的程序進行調(diào)試和/或測試,其中,所述目標機中包含調(diào)用轉(zhuǎn)向模塊,所述調(diào)用轉(zhuǎn)向模塊包括轉(zhuǎn)向配置子模塊,配置被測試程序的被測函數(shù)進行一次轉(zhuǎn)向所需的配置項,所述配置項包含在所述轉(zhuǎn)向控制表中;轉(zhuǎn)向控制子模塊,識別主調(diào)函數(shù)與被調(diào)用函數(shù),并根據(jù)所述轉(zhuǎn)向控制表中相應(yīng)的配置項,控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);和樁函數(shù)調(diào)用子模塊,根據(jù)轉(zhuǎn)向控制子模塊的當前調(diào)用轉(zhuǎn)向控制,調(diào)用相應(yīng)的測試專用函數(shù)以提供對被測函數(shù)的測試。
2.根據(jù)權(quán)利要求1所述的程序調(diào)測系統(tǒng),其中,所述轉(zhuǎn)向控制表中包含多個轉(zhuǎn)向控制塊,每個轉(zhuǎn)向控制塊記錄一個被測函數(shù)的信息,包括函數(shù)名稱、函數(shù)原型、函數(shù)所在源文件及行號、是否存在補丁函數(shù)、補丁函數(shù)類型、補丁激活狀態(tài)標志;并且所述轉(zhuǎn)向控制塊的信息來源于調(diào)試數(shù)據(jù)庫,或編譯產(chǎn)生的過程文件,或相關(guān)dump工具。
3.根據(jù)權(quán)利要求1所述的程序調(diào)測系統(tǒng),進一步包括自擴展調(diào)試子模塊,用于在用戶代碼層次實現(xiàn)斷點調(diào)試,所述調(diào)試采用腳本語言描述,并利用行號棧實現(xiàn)單步跟蹤中的前后步定位;其中,對于C語言程序,利用逗號表達式在if、while、或switch控制語句中插裝轉(zhuǎn)向控制函數(shù),從而實現(xiàn)針對這些控制語句的單步跟蹤。
4.根據(jù)權(quán)利要求1所述的程序調(diào)測系統(tǒng),進一步包括測試程度評估單元,通過分析測試用例對函數(shù)中調(diào)用的覆蓋程度來評估對每個所述被測函數(shù)的測試程度,所述評估包括使用問號表達式、宏替換、與或短路的方法之一或其組合進行分支覆蓋率統(tǒng)計;以及在轉(zhuǎn)向控制函數(shù)中分析被調(diào)用函數(shù),結(jié)合忽略函數(shù)表實現(xiàn)測試評估標準的定制。
5.一種程序調(diào)測方法,包括以下步驟配置被測試程序的被測函數(shù)進行一次轉(zhuǎn)向所需的配置項;分析主調(diào)函數(shù)與被調(diào)用函數(shù),根據(jù)被測函數(shù)的所述轉(zhuǎn)向的配置項,控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);和根據(jù)轉(zhuǎn)向控制子模塊的當前調(diào)用轉(zhuǎn)向控制,調(diào)用相應(yīng)的測試專用函數(shù)進行測試。
6.根據(jù)權(quán)利要求5所述的方法,其中所述控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù)包括在每個被測函數(shù)的首部插入轉(zhuǎn)向控制函數(shù)的步驟,并且所述轉(zhuǎn)向控制函數(shù)采用以下方式中的任一種進行所述轉(zhuǎn)向控制函數(shù)的插入1)借助編譯器提供的插裝功能實現(xiàn)插裝;2)借助符號跳轉(zhuǎn)功能實現(xiàn)插裝;3)在C語言中借助逗號表達式實現(xiàn)插裝;4)手工方式插裝。
7.根據(jù)權(quán)利要求6所述的方法,其中所述轉(zhuǎn)向控制函數(shù)按如下步驟實現(xiàn)轉(zhuǎn)向1)判斷所述被測函數(shù)是否已定義了測試專用函數(shù);2)若已定義了測試專用函數(shù),則確定所述測試專用函數(shù)是否處于被激活狀態(tài);3)若所述補丁函數(shù)的狀態(tài)為已激活,則通過修改調(diào)用棧中的函數(shù)返回地址值實現(xiàn)轉(zhuǎn)向。
8.根據(jù)權(quán)利要求7所述的方法,其中轉(zhuǎn)向控制函數(shù)利用轉(zhuǎn)向控制表來實現(xiàn)轉(zhuǎn)向,并且所述分析主調(diào)函數(shù)與被調(diào)用函數(shù)的步驟包括1-1)從所述調(diào)用棧中提取最近兩個函數(shù)調(diào)用的返回地址;1-2)根據(jù)返回地址查詢所述轉(zhuǎn)向控制表,獲得所述主調(diào)函數(shù)與被調(diào)用函數(shù)的轉(zhuǎn)向控制塊。
9.根據(jù)權(quán)利要求5-8任一項所述的方法,其中所述測試操作包括通過查看或修改全局變量,或調(diào)用被測系統(tǒng)中的函數(shù)來構(gòu)造測試運行環(huán)境;調(diào)用被測函數(shù)發(fā)起測試;在被測函數(shù)的首部設(shè)置斷點,在單步跟蹤到該斷點時,用測試腳本查看和修改傳入的參數(shù)與全局變量,或調(diào)用其它函數(shù);和單步跟蹤到函數(shù)尾部時,用所述測試腳本查看和修改函數(shù)返回值與全局變量,或調(diào)用其它函數(shù)。
10.根據(jù)權(quán)利要求9所述的方法,進一步包括從調(diào)試操作生成測試腳本,所述生成測試腳本滿足以下要求1)在一次調(diào)試的任意檢視操作步驟中,能夠使用測試斷言判斷運行情況是否與期望值相符;2)在調(diào)試中,支持在用戶操作界面查看當前范圍的各個變量取值,當某些變量被選中時,自動按當前取值生成所述測試斷言;3)當運行斷點處于函數(shù)的首部與尾部時,用戶能夠有選擇地將調(diào)試操作記錄為測試腳本,所述調(diào)試操作包括查看變量、修改變量、調(diào)用函數(shù);以及4)在一次調(diào)試后生成的測試腳本中,能夠以手工方式進行調(diào)整。
全文摘要
本發(fā)明提供了一種程序測試系統(tǒng)及方法,用以提高程序測試效率。該方法包括配置被測試程序的被測函數(shù)完成一次轉(zhuǎn)向所需的配置項;識別主調(diào)函數(shù)與被調(diào)用函數(shù),控制主調(diào)函數(shù)的當前調(diào)用轉(zhuǎn)向到測試專用函數(shù);和根據(jù)轉(zhuǎn)向控制子模塊的當前調(diào)用轉(zhuǎn)向控制,調(diào)用相應(yīng)的測試專用函數(shù)進行測試。本發(fā)明還支持基于函數(shù)調(diào)用的、可定制標準的測試評估方式。本發(fā)明有助于軟件研發(fā)中,特別是C語言項目研發(fā)中,大幅提升調(diào)測的工作效率,提高測試操作易用性,并有助于測試質(zhì)量提升。
文檔編號G06F11/36GK1949187SQ20061014519
公開日2007年4月18日 申請日期2006年11月17日 優(yōu)先權(quán)日2006年11月17日
發(fā)明者曹修洪 申請人:深圳市領(lǐng)測科技有限公司
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1