使用Troll对ARM Cortex-M处理器进行系统内核调试
Troll是用于ARM Cortex-M系統的C語言源代碼級調試器,可通過高端的blackmagic硬件調試探針進行訪問,并且還可以使用blackmagic的定制工具vx / blackstrike。目前Troll只支持以C編程語言編寫的源代碼程序的源代碼級調試,并以ELF格式編譯為可執行文件,其中也包含DWARF調試格式信息。
在此請大家注意,Troll是調試器的一個非常特殊的例子:
1. 它只針對基于ARM Cortex-M的系統
2. 源代碼調試僅支持C語言
3. 只支持blackmagic和blackstrike硬件調試探針
4. Trevroll本身是用C++編寫的
5. Troll本身嚴重依賴于Qt框架
以下是Troll的圖形用戶界面截圖,截至2017.2.28:
下面是上面截圖的注釋版本,顯示了Troll的各個部分的含義:
以下是一個簡化的,更具有實戰性質的日常使用的屏幕截圖,截至2017. 2.28 :
測試Troll
對Troll的測試是非常簡單和容易的,為了方便調試和評估,我會在靜態測試驅動模式對Troll進行測試。在這種模式下,我沒有建立與實時目標系統的連接,而是讓Troll從文件讀取目標內存和寄存器的內容。這樣,Troll就不會調用任何其他依賴的外部工具,測試所需的所有數據都將從具有硬編碼名稱的文件中獲取。這種靜態測試驅動器的操作方式主要是對Troll進行快速原型設計和調試,以及展示其各個功能。
讓我首先從github把它的源代碼復制過來,并初始化和更新子模塊。
git?clone?https://github.com/stoyan-shopov/troll.gitcd?troll git?submodule?init git?submodule?update接下來,就是構建Troll。由于Troll利用的是Qt框架,所以我更喜歡在Qt Creator IDE中構建Troll,但也可以直接使用qmake和make實用程序來構建它。
最后,從以下這個鏈接可以獲取一個靜態測試驅動的測試文件集:
https://github.com/stoyan-shopov/troll-test-drive-snapshots
在troll的工作目錄中提取troll-test-drive-files目錄。
現在測試準備都已經設置好了,就讓我開始運行Troll吧!
Troll的運行原理
截至目前,Troll已經斷斷續續地發展了大約六個月,截至目前Troll項目還處于實驗階段,非常不成熟。由于該代碼目前看起來非常具有攻擊性,且代碼很小,所以我認為它看起來很有發展潛力。一般的Troll代碼只有兩個源代碼文件,即troll.cxx和libtroll.hxx。文件troll.cxx中的代碼是調試器的前端,它能驅動圖形用戶界面并與正在調試的目標設備進行通信,troll.cxx文件大致包含1500行代碼。文件libtroll.hxx中的代碼負責對DWARF調試信息進行解碼,并為前端提供易于使用的信息,例如如何展開目標調用棧、數據對象的數據類型、數據對象所在的位置生成的機器代碼的目標、生成的地址或地址對應于源代碼中的哪一行(這對于在斷點上的操作是有用的)、子程序中的局部變量是多少等等。該文件目前大約有2400行代碼。這樣算起來,troll.調試器前端(在文件troll.cxx中)的代碼和調試信息處理引擎(在libtroll.hxx文件中)總共大約有4000行代碼。
盡管在許多方面的功能還是不完整的,但這4000行代碼當前還是提供了以下這些調試功能:
1. 目標調用棧的展開,包括從中斷服務程序中進行的堆棧展開,
2. 結構化的數據顯示, 數組顯示,數據結構分層顯示,支持位字段以及將C語言枚舉器的值解碼為符號名稱
3. 會在正在調試的程序中顯示當前源代碼位置,并可選擇性地拆卸源代碼
4. 提供源代碼程序中的子程序(C函數),全局和本地(子程序)數據對象的列表,以及源代碼映射到子程序和數據對象的定義
5. 目標執行控制,對斷點進行設置或清除,步進指令,恢復、暫停和重新啟動目標執行,
6. 目標閃存編程和驗證
troll的代碼需要不斷地增長,才能完全順利地支持上述所有功能,但是如何利用這4000行代碼來支持上面描述的這些功能呢?
為了讓troll的代碼盡可能保持簡潔,所以在實現以上那些功能時要注意:
1. ?troll不會嘗試支持除ARM Cortex-M以外的任何目標架構,以及除C語言之外的任何目標源代碼語言,此外,troll以C ++編寫,并大量使用Qt框架,以及Qt框架提供的功能
2. 在正常情況下,調試器會利用一些庫來提供對編譯器生成的可執行文件的結構化訪問,例如,以ELF文件格式。除此之外,調試器還會訪問調試信息部分和駐留在目標中生成的機器代碼。例如,libbfd庫、二進制文件描述符庫或libelf庫。由于troll不使用這樣的庫,所以為了在ELF文件格式的編譯器生成的可執行文件中找到DWARF調試信息部分,troll將簡單地執行objdump實用程序,以顯示調試信息部分的位置,然后解析objdump的函數輸出,并最終使用objdump實用程序提供的信息來簡單地讀取調試信息部分(通過簡單的文件訪問操作)。利用幾行C ++代碼,而不是整合和利用庫,如libbfd / libelf庫。此外,為了提取駐留在目標中的機器代碼,troll會執行objcopy實用程序,以生成ELF可執行文件中的s-record文件(通常用于編程目標芯片)。解析s-record文件非常簡單,只需要幾行C ++代碼,并且不需要使用庫,如libbfd / libelf。
3. 同樣,troll不使用反匯編庫,例如,libopcodes庫,而是運行objdump實用程序,以生成目標可執行ELF文件的反匯編列表,最后解析出反匯編輸出,為此輸出構建一個索引,并使用索引為目標地址提供反匯編文本。這種方法非常簡單,只需幾行源代碼即可實現,避免了對外部庫進行重組。
4. 存在訪問DWARF調試信息的高級通用庫,如libdwarf庫。troll的一個關鍵設計就是不使用這樣的庫,特別是libdwarf庫。troll是我第三個嘗試編寫的調試器,所以我知道,當創建一個功能非常有限的專用調試器,如troll 時,解碼和處理DWARF調試信息就會變得更簡單,更有效率,例如:
(1)在現在的程序中,可以對調用棧進行追溯,
(2)顯示本地和全局變量的位置,
(3)變量的數據類型是什么,?
(4)目標設備地址對應于源代碼中的哪一行,以便可以在那里設置一個斷點,
(5)通過目標設備地址所對應的源代碼文件,顯示出源代碼的反匯編。
通用庫(如libdwarf)很難提供這樣的功能,因為它們只能提供對DWARF調試信息的相對較低級別的訪問。
總而言之,就是不要使用通用庫來通過troll訪問DWARF調試信息,因為這會使troll代碼更簡單、更小、更直接、更高效、更容易維護、理解和修改。
5. ?FORTH,這一步實現起來,需要非常復雜的技術,因為由編譯器生成的設備代碼程序中的變量的位置以及如何展開目標調用棧都可能是復雜的。在DWARF中,通過定義一個虛擬的,面向堆棧的設備以及為該設備定義的一組指令來解決這個問題。這實質上是FORTH語言。在troll中,數據對象位置的計算和調用棧unwind都會被寫入FORTH。
原文發布時間為:2017年6月4日 本文作者:xiaohui 本文來自云棲社區合作伙伴嘶吼,了解相關信息可以關注嘶吼網站。 原文鏈接
總結
以上是生活随笔為你收集整理的使用Troll对ARM Cortex-M处理器进行系统内核调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dubbo之多版本
- 下一篇: Windows 下的 7 种 DLL 劫