GDB體系結構(三)
4.9 與GDB的介面
GDB基本上是一個命令列偵錯程式。隨著時間的推移,人們已經嘗試了各種方案,使其成為一個圖形視窗偵錯程式,但儘管所有的時間和精力,這些都沒有被普遍接受。
命令列介面
命令列介面使用標準GNU庫讀取線來處理與使用者的逐個字元互動。 Readline處理行編輯和命令完成等事情;使用者可以執行諸如使用游標鍵返回到一行並修復字元之類的操作。
然後,GDB接受readline返回的命令,並使用命令表的級聯結構進行查詢,其中命令的每個連續字選擇另一個表。例如,設定列印元件80涉及三個表;首先是所有命令的表,第二個是一個選項表可以被設定,並且第三是有價值的列印選項,其中的元素是限制從像的集合體的印刷物件的數目的一個表字符串或陣列。一旦級聯表呼叫了實際的命令處理函式,它就會獲得控制權,並且引數解析完全取決於函式。一些命令,如跑,同樣處理他們的論據傳統的C ARGC / argv的標準,而另一些,如列印,假設該行的其餘部分是一個單一的程式語言表達,給整條生產線轉移到語言 - 特定的解析器。
機器介面
提供除錯GUI的一種方法是使用GDB作為圖形介面程式的一種“後端”,將滑鼠點選轉換為命令並將列印結果格式化為視窗。這已經被多次使用,包括KDbg和DDD(資料顯示偵錯程式),但它不是理想的方法,因為有時結果被格式化為人類可讀性,省略細節並依賴於人類提供上下文的能力。
為了解決這個問題,GDB有一個備用的“使用者”介面,簡稱機器介面或MI。它基本上仍然是一個命令列介面,但命令和結果都有額外的語法,使一切都顯式 - 每個引數都用引號括起來,複雜的輸出有子組的分隔符和元件的引數名。此外,MI命令可以使用在結果中回顯的序列識別符號作為字首,確保報告的結果與正確的命令匹配。
要檢視兩種形式的比較方式,這是一個正常的步驟命令和GDB的響應:
(gdb) step
buggy_function (arg1=45, arg2=92) at ex.c:232
232 result = positive_variable * arg1 + arg2;
使用MI,輸入和輸出更加冗長,但其他軟體更容易準確地解析:
4321-exec-step 4321^done,reason="end-stepping-range", frame={addr="0x00000000004004be", func="buggy_function", args=[{name="arg1",value="45"}, {name="arg2",value="92"}], file="ex.c", fullname="/home/sshebs/ex.c", line="232"}
Eclipse [ecl12]開發環境是MI最著名的客戶端。
其他使用者介面
其他前端包括一個名為GDBtk或Insight的基於tcl / tk的版本,以及一個名為TUI的基於curses的介面,最初由Hewlett-Packard提供。 GDBtk是使用tk庫構建的傳統多層圖形介面,而TUI是分屏介面。
4.10 發展程序
維護者
作為一個原始的GNU程式,GDB開發遵循“大教堂”開發模式。最初由Stallman編寫,然後GDB經歷了一系列“維護者”,每個人都是架構師,補丁審閱者和釋出經理的組合,只能訪問少數Cygnus員工的原始碼庫。
1999年,GDB遷移到公共原始碼庫,並擴充套件到由數十名維護者組成的團隊,由數十名擁有提交許可權的人員提供幫助。這大大加速了開發,每週10次提交增長到100或更多。
測試測試
由於GDB是高度特定於系統的,在計算機中具有從最小到最大的系統的大量埠,並且具有數百個命令,選項和使用方式,即使是經驗豐富的GDB黑客也難以預測所有變化的影響。
這就是測試套件的用武之地。測試套件包含許多測試程式和expect指令碼,使用一個名為DejaGNU的基於tcl的測試框架。基本模型是每個指令碼在除錯測試程式,傳送命令然後將輸出與正則表示式進行模式匹配時驅動GDB。
該測試套件還能夠對實時硬體和模擬器進行交叉除錯,並具有特定於單一體系結構或配置的測試。
在2011年底,測試套件包括大約18,000個測試用例,包括基本功能測試,特定語言測試,體系結構特定測試和MI測試。其中大多數都是通用的,可以執行任何配置。預計GDB貢獻者將在修補源上執行測試套件,並且不會觀察到任何迴歸,並且預計新測試將伴隨每個新功能。但是,由於沒有人可以訪問可能受更改影響的所有平臺,因此很少能夠獲得零故障;對於為本機除錯配置的中繼快照,10--20次故障通常是合理的,而某些嵌入式目標將有更多故障。
4.11 得到教訓
開放式發展勝利
GDB最初是“大教堂”開發過程的典範,其中維護者密切控制源,外部世界只通過定期快照看到進展。這是通過補丁提交的相對不足來合理化的,但封閉的過程實際上是在阻止補丁。由於採用了開放式過程,補丁的數量比以往任何時候都大得多,質量也一樣好或更好。
制定計劃,但期望改變
開源開發過程本質上有點混亂,因為不同的人在程式碼上工作了一段時間,然後消失了,讓其他人繼續。
但是,制定開發計劃併發布它仍然是有意義的。它可以幫助指導開發人員處理相關任務,可以向潛在的資助者展示,並讓志願者思考他們可以做些什麼來推進它。
但是不要試圖強迫日期或時間框架;即使每個人都對一個方向充滿熱情,人們也不太可能保證全職工作的時間足夠長,以便在選定的日期之前完成。
就此而言,如果計劃已經過時,請不要堅持計劃本身。很長一段時間,GDB有一個計劃重組為一個libgdb庫,它有一個定義良好的API,可以連結到其他程式(特別是那些帶有GUI的程式);甚至更改了構建過程以構建libgdb.a作為中間步驟。雖然這個想法從那時起就定期出現,但Eclipse和MI的首要地位意味著圖書館的主要理由已被迴避,截至2012年1月,我們已經放棄了圖書館的概念,並且正在摒棄現在毫無意義的程式碼。
如果我們無限智慧,情況會很好
在看到我們做出的一些改變之後,您可能會想:為什麼我們不首先做正確的事情?好吧,我們還不夠聰明。
當然,我們可以預料到GDB將會非常受歡迎,並且將被移植到數十個和幾十個本地和交叉架構中。如果我們知道這一點,我們可以從gdbarch物件開始,而不是花費數年時間來升級舊的巨集和全域性變數;同上目標向量。
當然,我們可以預期GDB將與GUI一起使用。畢竟在1986年,Mac和X Window系統已經出現了兩年!我們可以將其設定為非同步處理事件,而不是設計傳統的命令介面。
真正的教訓是,並非GDBers愚蠢,但我們不可能足夠聰明地預測GDB將如何發展。 1986年,視窗和滑鼠介面無處不在,一點也不清楚;如果GDB的第一個版本完全適合GUI使用,我們看起來就像天才一樣,但它本來就是運氣。相反,通過使GDB在更有限的範圍內有用,我們構建了一個使用者群,可以在以後進行更廣泛的開發和重新設計。
學會過不完整的過渡
嘗試完成過渡,但它們可能需要一段時間;期望和他們一起生活不完整。
在2003年的GCC峰會上,Zack Weinberg對海灣合作委員會的“不完整過渡”感到遺憾,其中引入了新的基礎設施,但舊的基礎設施無法移除。 GDB也有這些,但我們可以指出已經完成的一些轉換,例如目標向量和gdbarch。即便如此,它們可能需要數年才能完成,同時必須保持偵錯程式執行。
不要太依賴於程式碼
當你花費很長時間使用單一程式碼時,它是一個重要的程式,也支付賬單,它很容易附加到它,甚至模擬你的思想以適應程式碼,而不是相反。
別。
程式碼中的所有內容都源於一系列有意識的決策:一些受到啟發,有些受到啟發。 1991年巧妙的節省空間的技巧與2011年的數GB RAM相比毫無意義。
GDB曾經支援Gould超級計算機。當他們在2000年左右關閉最後一臺機器時,確實沒有任何意義來保持這些位置。這一集是GDB過時流程的起源,現在大多數版本都包括某些部分的退役。
實際上,桌面上或已在進行中有許多根本性的變化,包括採用Python指令碼編寫,支援高度並行多核系統的除錯,以及重新編碼為C ++。這些變化可能需要數年才能完成;現在更有理由開始使用它們了。