技術(shù)頻道

娓娓工業(yè)
您現(xiàn)在的位置: 中國傳動網(wǎng) > 技術(shù)頻道 > 技術(shù)百科 > GDBstub的剖析與改進(jìn)

GDBstub的剖析與改進(jìn)

時間:2006-04-25 10:13:00來源:0

導(dǎo)語:?GDBstub的剖析與改進(jìn)
摘要:   本文討論了GDB遠(yuǎn)程調(diào)試技術(shù)在調(diào)試內(nèi)核、嵌入式系統(tǒng)中的實(shí)現(xiàn),簡要闡述GDB宿主機(jī)和GDB遠(yuǎn)程串行協(xié)議,詳細(xì)分析GDB調(diào)試代理在內(nèi)核層、應(yīng)用層的各種實(shí)現(xiàn)方法。并提出了一種在不修改操作系統(tǒng)內(nèi)核前提下調(diào)試應(yīng)用程序的方法。這種方法可移植性強(qiáng),而且消除了修改系統(tǒng)內(nèi)核可能帶來的隱患,減少了因修改內(nèi)核而帶來的工作量。在調(diào)試微內(nèi)核操作系統(tǒng)服務(wù)的應(yīng)用中表明,此方法非常有效。 關(guān)鍵詞:   遠(yuǎn)程調(diào)試;stub;GDBserver; KGDB;嵌入式系統(tǒng)調(diào)試 Abstract:   This thesis discusses the realization of GDB remote debugging technology in kernel and embedded system. Firstly it describes the GDB host and GDB Remote Serial Protocol, then it analyses in detail the realization of GDBstub on kernel layer and application layer, at last the authors give a new method for debugging application while the OS kernel doesn’t be modified. This method has strong portability, and it eliminates the hidden trouble of OS kernel modification, also it reduces the workload subject to OS kernel modification. The application in debugging OS service of micro-kernel system shows that this method is reasonably efficient. Key words:   Remote debugging; stub; GDBserver; KGDB; embedded system debugging 1、引言   調(diào)試是開發(fā)過程中必不可少的環(huán)節(jié),然而內(nèi)核、嵌入式系統(tǒng)的調(diào)試不同于傳統(tǒng)的調(diào)試系統(tǒng)。通常嵌入式系統(tǒng)不具備使用本地調(diào)試器的能力,由于:   系統(tǒng)自身的資源有限。內(nèi)存小,輸入輸出設(shè)備不能用于調(diào)試。   傳統(tǒng)的調(diào)試系統(tǒng)需要文件系統(tǒng),嵌入式系統(tǒng)通常無文件系統(tǒng),內(nèi)核調(diào)試時還不支持文件系統(tǒng)。   調(diào)試器的運(yùn)行本身需要操作系統(tǒng)的支持,因此無法實(shí)現(xiàn)操作系統(tǒng)內(nèi)核的調(diào)試。   最有效的解決方法是采用遠(yuǎn)程調(diào)試技術(shù)。遠(yuǎn)程調(diào)試是指調(diào)試器運(yùn)行的環(huán)境(主機(jī))和被調(diào)試的系統(tǒng)(目標(biāo)機(jī))在物理上是分離的,通過串口或者網(wǎng)絡(luò)進(jìn)行連接的調(diào)試技術(shù)。   GNU免費(fèi)提供的GDB就擁有強(qiáng)大的遠(yuǎn)程調(diào)試功能,它能夠使開發(fā)人員以遠(yuǎn)程調(diào)試的方式單步執(zhí)行目標(biāo)平臺上的程序代碼、設(shè)置斷點(diǎn)、查看內(nèi)存,并同目標(biāo)平臺交換信息。GDB遠(yuǎn)程調(diào)試的實(shí)時、動態(tài)、方便、免費(fèi)等優(yōu)點(diǎn)使它逐漸成為嵌入式開發(fā)首選的調(diào)試方案。   遠(yuǎn)程調(diào)試系統(tǒng)由三部分組成:主機(jī)上的本地調(diào)試器,目標(biāo)機(jī)上的調(diào)試代理,遠(yuǎn)程調(diào)試協(xié)議。如圖1。對應(yīng)于GDB遠(yuǎn)程調(diào)試系統(tǒng)的三部分:GDB,GDBstub, GDB遠(yuǎn)程串行協(xié)議。下面就這三部分進(jìn)行分析。 圖1. 遠(yuǎn)程調(diào)試系統(tǒng) 2、RSP協(xié)議   GDB RSP(Remote Serial Protocol)定義了GDB宿主機(jī)與被調(diào)試目標(biāo)機(jī)進(jìn)行通信時數(shù)據(jù)包的格式。信息的格式是:$數(shù)據(jù)#校驗(yàn)碼。多數(shù)的信息都使用ASCII碼,數(shù)據(jù)由一系列的ASCII碼組成,校驗(yàn)碼是由兩個16進(jìn)制數(shù)組成的單字節(jié)校驗(yàn)碼。接受方接受數(shù)據(jù)并校驗(yàn),若正確則回應(yīng)“+”,錯誤則回應(yīng)“-”。通信的內(nèi)容包括讀寫數(shù)據(jù)、控制程序運(yùn)行、報告程序狀態(tài)等命令。RSP的基本命令從通信對話角度可以分為兩種: 1) 請求 ?:讀當(dāng)前系統(tǒng)狀態(tài) g:讀所有寄存器 G:寫所有寄存器 m:讀內(nèi)存 M:寫內(nèi)存 c:繼續(xù)執(zhí)行 s: 單步執(zhí)行 k:終止進(jìn)程 2) 答復(fù) “”:告訴GDB上次請求命令不支持。 E:告訴GDB出錯 OK:上次請求正確 W:系統(tǒng)在exit_status狀態(tài)下退出。 X:系統(tǒng)在signal信號下終止。 S:系統(tǒng)在signal信號下停止。 O:告訴GDB控制臺輸出,這也是唯一向GDB發(fā)出的命令 3、GDB遠(yuǎn)程調(diào)試功能   調(diào)試內(nèi)核時通常還沒有文件系統(tǒng),而且多數(shù)嵌入式由于自身資源的限制不具備文件系統(tǒng),因此將與文件系統(tǒng)有關(guān)的源文件、目標(biāo)文件及符號表都存放在主機(jī)上,由主機(jī)上的調(diào)試器處理。同樣,調(diào)試用的輸入輸出設(shè)備也是由主機(jī)提供。主機(jī)上的調(diào)試器接受用戶輸入的調(diào)試命令并進(jìn)行預(yù)處理,對于有些命令(如breakpoint)的處理就在主機(jī)GDB上實(shí)現(xiàn),不需要同目標(biāo)機(jī)進(jìn)行通信。當(dāng)然,更多的指令需要在目標(biāo)機(jī)上調(diào)試代理上實(shí)現(xiàn)的。主機(jī)將預(yù)處理完之后的命令根據(jù)RSP進(jìn)行封裝,發(fā)送給目標(biāo)機(jī)上的調(diào)試代理,調(diào)試代理接受命令后作相應(yīng)的處理,并返回信息給主機(jī)上的調(diào)試器。 4、目標(biāo)機(jī)上stub的實(shí)現(xiàn)   目標(biāo)機(jī)上stub的基本功能是與主機(jī)GDB進(jìn)行通信,實(shí)現(xiàn)讀寫內(nèi)存、寄存器,stop,continue。主機(jī)GDB同目標(biāo)機(jī)上stub進(jìn)行通信的通用模型如圖2: 圖2. GDB同目標(biāo)機(jī)上stub通信的通用模型   目標(biāo)機(jī)與主機(jī)通過硬件連接,被調(diào)試部分插入stub,GDB與被調(diào)試部分通過RSP進(jìn)行通信。根據(jù)stub所處層的不同來實(shí)現(xiàn)不同層的調(diào)試,包括內(nèi)核層、應(yīng)用層的調(diào)試。 4.1 內(nèi)核層調(diào)試模型 圖3. 使用stub對內(nèi)核進(jìn)行調(diào)試   如圖3,將stub插入到內(nèi)核里就可以實(shí)現(xiàn)內(nèi)核的調(diào)試了。Linux內(nèi)核調(diào)試機(jī)制KGDB就是使用這種模式。KGDB可以分為初始化模塊和控制模塊。 4.1.1初始化模塊   修改異常處理函數(shù),使得在異常發(fā)生時都進(jìn)入函數(shù)handle_exception(),這樣GDB就能夠捕獲這些異常。初始化之后使用breakpoint()函數(shù)將系統(tǒng)控制權(quán)直接交給GDB。KGDB對異常處理函數(shù)的修改基本上可以分為二種。 定義宏CHK_REMOTE_DEBUG #define CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,after) { if (linux_debug_hook != (gdb_debug_hook *) NULL && !user_mode(regs)) { (*linux_debug_hook)(trapnr, signr, error_code, regs) ; after; } }  改變程序的流程,以int3的處理函數(shù)為例 #define DO_VM86_ERROR(trapnr, signr, str, name) asmlinkage void do_##name(struct pt_regs * regs, long error_code) { CHK_REMOTE_DEBUG(trapnr,signr,error_code,regs,goto skip_trap) do_trap(trapnr, signr, str, 1, regs, error_code, NULL); skip_trap: return; } 展開DO_VM86_ERROR (3,SIGTRAP,"int3",int3) asmlinkage void do_int3(struct pt_regs *regs, long error_code) { if (linux_debug_hook != ( gdb_debug_hook *)NULL&&! user_mode(regs)) { (*linux_debug_hook)(3, SIGTRAP, errorcode, regs); goto skip_trap; } do_trap(3, SIGTRAP, "int3", 1, regs, error_code, NULL); skip_trap: return; } 從以上代碼可見,進(jìn)入內(nèi)核調(diào)試狀態(tài)之后,異常處理函數(shù)就是handle_exception(),程序流程跳過了非調(diào)試狀態(tài)時的處理函數(shù)do_trap。 不改變程序的流程,以異常divide_error 的處理函數(shù)為例 #define DO_VM86_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) asmlinkage void do_##name(struct pt_regs * regs, long error_code) { …… do_trap(trapnr, signr, str, 1, regs, error_code, &info); } 展開DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip) asmlinkage void do_divide_error (struct pt_regs *regs, long error_code) { if (linux_debug_hook != ( gdb_debug_hook *)NULL&&! user_mode(regs)) { (*linux_debug_hook)(3, SIGTRAP, errorcode, regs); } do_trap(0, SIGTRAP, "divide erro", 1, regs, error_code, &info); } 從以上代碼中看不出調(diào)試狀態(tài)跟非調(diào)試狀態(tài)的區(qū)別,然而我們看一下do_trap函數(shù)中可能會調(diào)用的函數(shù)die()。 void die(const char * str, struct pt_regs * regs, long err) { CHK_REMOTE_DEBUG(1,SIGTRAP,err,regs,) do_exit(SIGSEGV); }   由此可見,調(diào)試狀態(tài)下的異常處理函數(shù)還是進(jìn)入了handle_exception函數(shù)。不過與上面一種異常不同之處在于:異常處理函數(shù)在調(diào)試與非調(diào)試狀態(tài)下的程序流程是相同的,handle_exception只提供獲取系統(tǒng)當(dāng)時的狀態(tài),繼續(xù)運(yùn)行的結(jié)果還是do_exit。   雖然不是所有異常函數(shù)都是按上述兩種方法定義的,但本質(zhì)上都可以歸劃為其一,顯然絕大多數(shù)處理函數(shù)的修改屬于第二種,因?yàn)榈谝环N異常就是為調(diào)試準(zhǔn)備的。因此在目標(biāo)機(jī)具有調(diào)試用的輸出設(shè)備的情況下,完全可以不修改第二種異常處理函數(shù),因?yàn)閘inux內(nèi)核在非調(diào)試狀態(tài)下的異常處理函數(shù)已經(jīng)輸出必要的狀態(tài)信息、出錯信息。 4.1.2控制模塊   在控制模塊完成與主機(jī)GDB的通信,具體流程如圖4,handle_exception函數(shù)首先判斷CPU是否處于VM86模式或用戶態(tài),若是則返回,可見KGDB只調(diào)試內(nèi)核態(tài)程序。然后接受GDB發(fā)來的信息,根據(jù)接受的信息作出相應(yīng)的操作和回復(fù)。流程圖的虛線框內(nèi)是所有GDBstub中handle_exception函數(shù)的通用流程。 4.2 應(yīng)用程序調(diào)試模型   在嵌入式Linux開發(fā)領(lǐng)域里調(diào)試應(yīng)用程序常用調(diào)試代理工具GDBserver,其工作原理并不是將stub編譯在被調(diào)試應(yīng)用程序內(nèi),而是把被調(diào)試程序作為GDBserver的子進(jìn)程,這樣GDBserver就可以利用內(nèi)核提供的代碼跟蹤機(jī)制(ptrace)監(jiān)控被調(diào)試進(jìn)程的運(yùn)行,從而來完成調(diào)試任務(wù)。此工作原理同GDB本地調(diào)試相似。其調(diào)試模型如圖5。GDBserver的工作流程是:GDBserver創(chuàng)建子進(jìn)程->綁定跟蹤ptrace(ptrace_traceme,,)->從主機(jī)傳來的各種調(diào)試命令通過GDBserver轉(zhuǎn)化為各種操作需求的ptrace。顯然,如果要用GDBserver來進(jìn)行遠(yuǎn)程調(diào)試的話,就需要內(nèi)核操作系統(tǒng)的支持,包括子進(jìn)程、代碼跟蹤機(jī)制,這樣對于其他嵌入式系統(tǒng)內(nèi)核工作量會比較大。而且ptrace也有其局限性,比如只能跟蹤它的子進(jìn)程,在調(diào)試進(jìn)程和被調(diào)試進(jìn)程之間傳送一個長字的數(shù)據(jù)。使用通用的調(diào)試模式工作量會更小。如圖6,將stub編譯在應(yīng)用程序中,并在應(yīng)用程序入口處就插入斷點(diǎn),程序開始就上控制權(quán)交給GDB,之后的流程跟內(nèi)核層調(diào)試類似。 圖4. GDBKGDB中handle_exception函數(shù)流程 圖5. 使用GDBserver對應(yīng)用程序進(jìn)行調(diào)試 圖6. 使用stub對應(yīng)用程序進(jìn)行調(diào)試 5. 不修改內(nèi)核前提下調(diào)試應(yīng)用程序   GDB實(shí)現(xiàn)設(shè)置斷點(diǎn)的方式是使用內(nèi)存的讀寫,即將原指令用一個trap指令代替,使得程序執(zhí)行到該指令時產(chǎn)生單步調(diào)試中斷,然后就進(jìn)入異常處理函數(shù),針對調(diào)試器的各種操作處理函數(shù)需要作出相應(yīng)的操作。不同的系統(tǒng)提供不同的調(diào)試異常指令,如int3,trap2等,顯然對于使用這些硬件平臺提供的斷點(diǎn)指令為了實(shí)現(xiàn)GDBstub調(diào)試功能需要改寫這些指令異常處理函數(shù)。因此一般的調(diào)試系統(tǒng)器或調(diào)試代理都需要涉及單步調(diào)試指令的處理函數(shù),需要系統(tǒng)內(nèi)核的支持。上面提到的KGDB修改了異常處理函數(shù),GDBserver需要系統(tǒng)內(nèi)核提供ptrace函數(shù)。這種方法存在一些不足之處:修改內(nèi)核工作量大,移植性差。針對這些情況我們可以采用另一種斷點(diǎn)實(shí)現(xiàn)方案:在stub中定義一個設(shè)置斷點(diǎn)函數(shù)。   斷點(diǎn)函數(shù)模擬調(diào)試異常指令,實(shí)現(xiàn)保護(hù)現(xiàn)場、調(diào)用異常處理函數(shù)、恢復(fù)現(xiàn)場并將控制權(quán)交給被調(diào)試程序。斷點(diǎn)函數(shù)的基本流程如下。 #define BREAKPOINT __asm__ __volatile__(" bl ent_exception\n) void debug_trap() { __asm__ __volatile__( " ent_exception: \n" 保存現(xiàn)場 " bl handle_exception \n" " out_exception: \n" 恢復(fù)現(xiàn)場 ); } handle_exception()函數(shù)流程類似圖4中的虛線框部分。其中有一點(diǎn),也是這種方法實(shí)現(xiàn)的關(guān)鍵部分是:斷點(diǎn)指令的替換。斷點(diǎn)設(shè)置時從GDB傳過來的硬件平臺提供的斷點(diǎn)異常指令的二進(jìn)制碼,必須將此二進(jìn)制碼替換成在stub中新定義的BREAKPOINT二進(jìn)制碼,這樣才能進(jìn)入調(diào)試異常處理函數(shù)。因此在handle_exception()函數(shù)中,如果收到的請求是“M”,則需要作些處理,流稱如圖7: 圖7. 替換指令   這種方法理論上在內(nèi)核調(diào)試和應(yīng)用程序調(diào)試中都可以使用,但在應(yīng)用程序的調(diào)試中其優(yōu)點(diǎn)更明顯。這種方法在寫stub時候不涉及內(nèi)核,在調(diào)試應(yīng)用程序時不需要切換到內(nèi)核模式下,直接在用戶模式中就可以完成。這種方法也存在些不足之處。為了實(shí)現(xiàn)現(xiàn)場保護(hù),要求用戶了解系統(tǒng)內(nèi)的寄存器。隨著stub本身復(fù)雜度的增加,它的正確性需要更多的檢驗(yàn)。 6、結(jié)束語 加stub的遠(yuǎn)程調(diào)試方法方便而有效,而且可以降低項(xiàng)目成本,在實(shí)際工作中得到廣泛的研究和應(yīng)用。本文提到在不修改內(nèi)核前提下調(diào)試應(yīng)用程序的方法已成功應(yīng)用于我們自己開發(fā)的微內(nèi)核結(jié)構(gòu)的操作系統(tǒng)里,為該系統(tǒng)的開發(fā)應(yīng)用提供良好的調(diào)試手段。當(dāng)然加stub的遠(yuǎn)程調(diào)試方法也存在一些不足。顯然stub的應(yīng)用是在串口通信的基礎(chǔ)上,因此串口處理函數(shù)以及stub自身處理函數(shù)的正確性是確保stub安全調(diào)試的前提。 參考文獻(xiàn) [1].李紅衛(wèi)李翠萍,kgdb調(diào)試Linux內(nèi)核肋剖析與改進(jìn),微型機(jī)與應(yīng)用,2004年第10期 [2].郭勝超,GDB遠(yuǎn)程調(diào)試及其在嵌入式Linux系統(tǒng)中的應(yīng)用,計算機(jī)工程與應(yīng)用,2004年第26卷第10期. [3].彭進(jìn)展,GRDBS:一種針對嵌入式系統(tǒng)的通用遠(yuǎn)程調(diào)試系統(tǒng),計算機(jī)工程,2003年2月第29卷第2期. [4] .Gatliff, Bill, Embedding with GNU: the gdb Remote Serial Protocol, Embedded Systems Programming, September 1999, p. 109. [5].Gilmore J, Shebs S, GDB Internals: A Guild to the Internals of the GNU Debugger, Free Software Foundation Inc.,1999.   作者單位:浙江大學(xué)計算機(jī)系   地址:浙江大學(xué)玉泉校區(qū)4舍230 310027  Email:liulin@zju.edu.cn

標(biāo)簽:

點(diǎn)贊

分享到:

上一篇:單片機(jī)破解的常用方法及應(yīng)對策略

下一篇:微能WIN-V63矢量控制變頻器在...

中國傳動網(wǎng)版權(quán)與免責(zé)聲明:凡本網(wǎng)注明[來源:中國傳動網(wǎng)]的所有文字、圖片、音視和視頻文件,版權(quán)均為中國傳動網(wǎng)(www.treenowplaneincome.com)獨(dú)家所有。如需轉(zhuǎn)載請與0755-82949061聯(lián)系。任何媒體、網(wǎng)站或個人轉(zhuǎn)載使用時須注明來源“中國傳動網(wǎng)”,違反者本網(wǎng)將追究其法律責(zé)任。

本網(wǎng)轉(zhuǎn)載并注明其他來源的稿件,均來自互聯(lián)網(wǎng)或業(yè)內(nèi)投稿人士,版權(quán)屬于原版權(quán)人。轉(zhuǎn)載請保留稿件來源及作者,禁止擅自篡改,違者自負(fù)版權(quán)法律責(zé)任。

網(wǎng)站簡介|會員服務(wù)|聯(lián)系方式|幫助信息|版權(quán)信息|網(wǎng)站地圖|友情鏈接|法律支持|意見反饋|sitemap

中國傳動網(wǎng)-工業(yè)自動化與智能制造的全媒體“互聯(lián)網(wǎng)+”創(chuàng)新服務(wù)平臺

網(wǎng)站客服服務(wù)咨詢采購咨詢媒體合作

Chuandong.com Copyright ?2005 - 2024 ,All Rights Reserved 版權(quán)所有 粵ICP備 14004826號 | 營業(yè)執(zhí)照證書 | 不良信息舉報中心 | 粵公網(wǎng)安備 44030402000946號