田 丹,李運喜,胡 寧,麥先根
(中航工業(yè) 西安航空計算技術研究所 三室,陜西 西安 710068)
開發(fā)任何一個軟件都不可避免地存在各種錯誤,通常程序員利用調試器來跟蹤程序執(zhí)行情況,定位錯誤產生的位置,找到引起錯誤的原因,最終改正錯誤。一般來說,調試器的主要功能是控制目標程序執(zhí)行過程,查看、修改目標程序對象,包括在目標程序中設置刪除斷點;源代碼級或匯編級單步執(zhí)行、連續(xù)執(zhí)行目標程序;查看、修改目標程序變量、寄存器和內存等。嵌入式軟件調試通常采用宿主機/目標機模式,借助通用計算機作為宿主機,在宿主機上編輯源代碼,使用交叉編譯器編譯生成目標機的可執(zhí)行代碼,通過通信介質將目標代碼下載到目標機上運行,使用交叉調試器進行跟蹤調試,其一般通用結構見圖1。
圖1 交叉調試結構
國外計算機業(yè)在嵌入式軟件調試領域發(fā)展很快,開發(fā)出多款功能強大、支持多種目標機的交叉調試器。目前國內的嵌入式系統(tǒng)發(fā)展迅速,對嵌入式軟件的開發(fā)環(huán)境也提出了新的要求,因此在此著手進行嵌入式軟件的源代碼級交叉調試器的設計與實現(xiàn)。
Eclipse項目是由IBM、Borland、Rational等多家軟件工具開發(fā)公司參與研究和推廣的新一代通用集成開發(fā)環(huán)境,核心是動態(tài)發(fā)現(xiàn)插件(Plug?in)的體系結構[1]。微內核形式的平臺核心負責處理基本環(huán)境的后臺工作,基于功能的單個插件專注于執(zhí)行特定的任務。通過集成來自不同供貨商的插件,Eclipse可以不斷擴展,實現(xiàn)各種不同的功能:支持C/C++開發(fā)的CDT(C/C++Develop?ment Toolkit)插件;支持Java開發(fā)調試的JDT插件;支持XML開發(fā)的WST插件;支持遠程系統(tǒng)開發(fā)的RSE(Re?mote System Explorer)插件;支持版本管理的CVS插件;支持模型驅動開發(fā)的GEF、EMF插件等。Eclipse當前已經成為主流的嵌入式軟件集成開發(fā)環(huán)境基礎平臺[2],其中集成有嵌入式軟件開發(fā)調試過程中的各種工具,如目標機應用程序項目管理、源代碼編輯、項目構建、交叉運行、交叉調試、交叉測試、固化、遠程系統(tǒng)查詢?yōu)g覽等[3]。
GDB是GNU提供的開放源代碼的源代碼級調試工具,可以用于C/C++等程序的跟蹤調試[4]。在嵌人式系統(tǒng)開發(fā)軟件中,開發(fā)人員能夠使用GDB以遠程調試的方式單步執(zhí)行目標平臺上的程序代碼、設置斷點、查看內存,和目標平臺交換信息。GDB同目標機交換信息的能力相當強大,勝過絕大多數(shù)的商業(yè)調試工具,甚至可以與某些低端仿真器媲美。同樣,與打印輸出等傳統(tǒng)的軟件調試手段相比,GDB遠程調試的動態(tài)、實時、方便等方面的優(yōu)勢非常明顯。
CDT是在Eclipse平臺上支持C/C++開發(fā)的工具插件,支持創(chuàng)建、編輯、資源管理、編譯、運行和調試本地C/C++程序[5]。CDT由一組相關聯(lián)插件組成,每個插件都作為一個獨立自主的項目運行。
CDT的本地調試大致分為3步:
(1)初始化運行環(huán)境。CDT需要初始化運行環(huán)境、設置被調試的目標文件、設置調試入口、確定源代碼位置和查找規(guī)則、設置和GDB調試器的通信鏈接參數(shù)等。啟動調試會話后,CDT創(chuàng)建并初始化調試對象、線程信息、斷點信息、寄存器信息、內存信息、源代碼信息等;
(3)開始調試。用戶發(fā)出調試命令后,CDT首先檢測被調試對象的狀態(tài),如此時對象已經運行則拋出異常(如被掛起),并向GDB發(fā)出continue命令;如被終止或沒有運行,則向GDB發(fā)出run命令,運行調試對象,直到觸發(fā)事件。當有事件被觸發(fā),CDT將收集事件發(fā)生時的目標機現(xiàn)場,根據(jù)該現(xiàn)場決定被調試的線程、斷點位置、源代碼位置以及目標機對象信息,并反饋給用戶,用戶可執(zhí)行下一條的調試命令,CDT通過MI接口將具體的調試命令傳遞給GDB執(zhí)行,依次循環(huán)直至完成本次調試。
CDT的調試支持部分包括CDT調試核心、CDT調試UI、CDT調試MI和 CDT調試啟動等插件,通過擴展上述插件,可啟動交叉調試器GDB,實現(xiàn)對遠程目標機程序的源代碼級交叉調試功能。
根據(jù)Eclipse、CDT以及GDB的以上功能特性,以Eclipse為交叉調試環(huán)境基礎平臺,調用CDT調試服務框架,擴展調試相關功能,將嵌入式交叉工具鏈無縫集成到交叉調試環(huán)境基礎平臺中。
交叉調試由CDT交叉調試支持、目標機服務器通信支持和交叉GDB,如圖2所示。CDT交叉調試擴展CDT的調試擴展服務,調用交叉GDB,提供遠程交叉調試支持。
圖2 交叉調試組成圖
CDT調試覆蓋基本的調試工具,包括調試啟動、調試視圖、斷點視圖、表達式視圖、變量視圖、反匯編視圖、內存視圖和源碼編輯器等。調試啟動管理調試啟動配置。調試視圖管理調試會話,顯示調試棧幀,提供調試操作。斷點視圖提供調試斷點管理功能,包括設置、刪除、關閉和打開斷點等操作。變量視圖提供局部變量和全局變量操作功能。寄存器視圖提供寄存器操作功能,在多核條件下,支持查看不同核上的寄存器。內存視圖提供內存操作。表達式視圖提供表達式求值功能。反匯編視圖支持反匯編調試。源碼編輯器提供源代碼級調試。
交叉調試擴展CDT,實現(xiàn)兩個新的插件:cross.de?bug.core和cross.debug.ui。cross.debug.core需要擴展命令工廠擴展點,實現(xiàn)交叉調試命令集;擴展調試器擴展點,啟動交叉調試GDB;實現(xiàn)符號表管理器,提供脫離GDB的符號表查詢接口,在GDB沒有啟動的情況下(如加載時)查詢符號地址;擴展調試啟動器擴展點,鏈接目標機服務器,根據(jù)調試類型加載目標文件。cross.debug.ui插件擴展調試運行類型擴展點,為支持的嵌入式操作系統(tǒng)添加專有的調試運行類型組,與該嵌入式操作系統(tǒng)相關的調試啟動歸屬于這個組;擴展調試器配置頁擴展點,配置調試參數(shù)如選擇目標機服務器、調試初始入口和加載配置等。
目標機服務器用于管理宿主機與目標機之間的通信鏈接,是嵌入式軟件集成開發(fā)環(huán)境與目標機的通信中心。目標機服務器可以管理多個目標機,同時向多個目標機發(fā)送數(shù)據(jù),可以同時接收多個目標機的數(shù)據(jù)。目標機服務器將開發(fā)環(huán)境中所有和目標機通信相關統(tǒng)一管理,并為開發(fā)工 具提供目標機通信接口。
樣品經濕法消化后,導入原子吸收分光光度計中,經火焰原子化后,吸收422.7 nm處的共振線,其吸收量與含量成正比,與標準系列比較定量。
目標機服務器提供目標機管理、數(shù)據(jù)傳輸、目標機通信、目標機通信連接檢查、命令管理、目標機事件管理、RSP數(shù)據(jù)處理、符號表管理、日志記錄等功能。
交叉GDB提供不同體系結構目標機系統(tǒng)的遠程調試支持,在調試啟動配置中可以選擇不同版本的交叉GDB。GDB和目標機服務器之間接口是MI協(xié)議。目標機服務器把MI協(xié)議命令轉化為RSP協(xié)議,發(fā)給目標機代理處理。
交叉調試設計為遠程調試模式,與CDT本地調試有所不同,交叉調試需要與待目標機的體系結構相符的交叉調試GDB;交叉調試需要和遠程目標機通信,這由目標機服務器負責;調試命令由GDB發(fā)給目標機服務器,返回信息由目標機服務器傳給GDB,再由CDT界面顯示。
交叉調試基本步驟為:
(1)初始化目標機系統(tǒng),建立宿主機與待調試目標機之間的通信通道,加載運行被調試的目標文件到目標機中;
(2)啟動交叉調試器。確定宿主機中和目標機上所運行程序對應的包含調試信息的目標文件,然后啟動宿主機上和目標機體系結構匹配的交叉調試器GDB,建立該交叉調試器和目標機服務器的通信鏈接,以后的調試命令通過該通信鏈接向目標機發(fā)送命令并接收目標機返回的信息;
(3)初始化交叉調試運行環(huán)境,建立交叉調試會話。啟動交叉調試會話后,CDT創(chuàng)建并初始化調試對象、遠程目標機中的線程信息、斷點信息、寄存器信息、內存信息、源代碼信息等;
(4)開始交叉調試。該過程與CDT的本地調試步驟(3)類似,GDB收到MI調試命令后,轉換為遠程串行協(xié)議(Remote Serial Protocol,RSP)命令,發(fā)給目標機服務器;目標機服務器將RSP命令發(fā)送給目標機執(zhí)行,并接收目標機返回的執(zhí)行結果信息和目標機程序執(zhí)行中觸發(fā)事件,送給GDB處理;GDB收到目標機報告的數(shù)據(jù),轉換為MI命令回復交給CDT;CDT根據(jù)MI命令回復確定該調試命令的執(zhí)行結果。
符號表是源碼級調試的必要功能。在本地調試過程中,由GDB管理符號表并提供查詢接口。交叉調試時,可能GDB尚未啟動,或者不具備查詢狀態(tài),不能從GDB獲得符號信息,需要調用脫離GCC工具鏈和GDB的符號表解析程序。解析程序包含4部分:Symbol類、Section類、ElfHeaher類、Elf類和符號表管理類 Symbol?Manager。
Symbol類描述符號相關信息,包括符號名字、符號地址、符號類型以及符號所屬段等數(shù)據(jù)。
Section類描述段相關信息,包括段名字、段類型、段屬性、裝入地址和段偏移及大小等數(shù)據(jù)。
ElfHeaher類描述Elf文件頭信息,包括文件類型、目標體系類型、處理器標識、文件入口地址、Elf頭偏移及大小、段表信息等數(shù)據(jù)。
Elf類解析帶有調試信息的目標文件信息,創(chuàng)建相關信息對象:一個ElfHeader對象、一組Section對象和一組Symbol對象。
SymbolManager類提供設置符號文件、根據(jù)源代碼行號查地址、根據(jù)地址查源代碼行號、根據(jù)地址查符號、根據(jù)符號查地址以及獲得指定段等接口。
交叉調試對CDT調試的擴展主要是在建立和目標機服務器的通信鏈接,啟動并初始化支持交叉調試的GDB方面,主要包括以下方面:
(1)擴展交叉調試命令集實現(xiàn)CrossCommandFacto?ry。CDT默認的調試命令集包含GDB的MI命令和部分CLI命令,需要加入新的命令如增加符號文件、根據(jù)源代碼行號查地址命令、根據(jù)地址查符號以及根據(jù)符號查地址等命令;
(2)擴展交叉調試器實現(xiàn)CrossDebugger。啟動交叉調試器需要找到符合目標機體系結構的GDB,添加符號表文件,把CDT建立的本地調試對象Target轉換為交叉調試對象CrossTarget以記錄遠程目標機的調試上下文,維護調試會話使用的目標機服務器鏈接等參數(shù);
(3)擴展交叉調試器配置實現(xiàn)CrossDebuggerPage。在調試啟動配置中添加交叉調試需要的參數(shù)配置界面;
(4)擴展交叉調試器啟動代理實現(xiàn)CrossLaunch?Delegate。根據(jù)配置鏈接目標機服務器指定要調試的目標機,加載待調試程序到目標機;還有可能需要重定位目標文件、設置所調試程序參數(shù);根據(jù)配置啟動交叉調試器,創(chuàng)建調試會話,初始化源代碼查找器。
本文主要研究以開源的Eclipse和CDT項目為依托,在分析Eclipse、CDT和GDB的功能特性的基礎上,根據(jù)CDT的擴展服務,實現(xiàn)在宿主機上利用交叉調試GDB,調試遠程目標機程序的源代碼級交叉調試功能。該交叉調試支持通用的調試操作如設置刪除斷點、源代碼級或匯編級單步執(zhí)行、連續(xù)執(zhí)行目標程序、查看/修改目標程序變量、寄存器、內存和查看表達式等。進一步,在嵌入式軟件開發(fā)階段,開發(fā)者必須要對目標系統(tǒng)運行狀態(tài)具有完全的觀察和控制能力,例如硬件的各種寄存器、內存空間使用情況、CPU利用率,操作系統(tǒng)的信號量、消息隊列、任務、堆棧等對象和系統(tǒng)任務之間的通信情況、任務的執(zhí)行軌跡,這將是進一步的工作。
[1]Anon.Fortify audit workbench user guide[EB/OL].[2012?11?17].http://www.wenku.baidu.com/link?u.
[2]魏楚元,李陶深,張增芳.Eclipse:基于插件的下一代通用集成開發(fā)環(huán)境[J].計算機應用與軟件,2005,22(6):38?40.
[3]劉芳,臧威.基于Eclipse平臺的嵌入式交叉調試環(huán)境MRTOS[J].電子科技,2013,26(5):18?21.
[4]Free Software Foundation.GDB user manual[EB/OL].(2006?12?13) [2007?01?09].http://sourceware.org/gdb/current/on?linedocs/gdb?toc.html.
[5]Anon.Eclipse IDE C/C++development user guide[EB/OL].[2013?11?28].http://www.www.docin.com...570.html.
[6]王興杰,李允,江浩,等.基于Linμx的嵌入式交叉開發(fā)技術[J].計算機應用研究,2008(1):206?208,214.