SylixOS中AARCH64的GDB調試實現

1. GDB功能實現的框架

1.1 GDB的簡介

GDB是GNU開源組織發佈的一個強大的UNIX下程序調試工具。SylixOS中除Lite版本外,都可以實現GDB調試功能。
GDB可以對C和C++程序進行調試,它使用戶能在程序運行時觀察程序的內部結構和內存的使用情況。以下是GDB所提供的一些功能:

  1. 能監視程序中變量的值;
  2. 能設置斷點以使程序在指定的代碼行上停止執行;
  3. 能逐行執行代碼。

1.2 GDB的組成框架

GDB由gdb-server和gdb-host組成。
目標板使用gdb-server來啓動已經編譯好的代碼,執行斷點、單步等調試動作,同時通過網絡、串口等反饋調試需要的信息給gdb-host。
宿主機上運行gdb-host,解析gdb-server傳來的信息,同時,發送斷點、單步等動作給目標板。

2. SylixOS中GDB的實現

2.1 Base中已經實現的內容

在SylixOS中,gdb-server的主要通信流程和網絡通信框架,已經在Base中實現,代碼位置如下圖所示。
gdb-server的實現
這部分代碼邏輯中,已經完成和gdb-host的通信邏輯。當在RealEvo-IDE中的Debug界面,進行單步,運行到指定行,全速運行等操作時,gdb-host實際通過對應架構的xxxx-sylixos-elf-gdb.exe工具與板卡內的gdb-server進行通信。

2.2 ARCH需要實現的內容

在每個具體架構中,都存在dbg目錄,該目錄下對應有xxxDbg.c和xxxGdb.c文件,以及xxx_gdb.h文件,如下圖所示。
ARCH中GDB的實現

2.2.1 xxx_gdb.h的實現

xxx_gdb.h中主要實現與GDB相關的結構體變量定義和函數聲明。
比如,在AARCH64中,xxx_gdb.h 中對 GDB 相關結構體的定義如下程序清單所示:

/***************************************************************************
  最大寄存器數
***************************************************************************/
#define GDB_MAX_REG_CNT     34
/***************************************************************************
  寄存器集合結構
***************************************************************************/
typedef struct {
    INT         GDBR_iRegCnt;                          /* 寄存器數量                 */
    struct {
        ULONG   GDBRA_ulValue;                         /* 寄存器值                   */
    } regArr[GDB_MAX_REG_CNT];                        /* 寄存器數組                  */
} GDB_REG_SET;

在該結構體中需要定義gdb-server監控和傳輸的寄存器數量,以及爲每個寄存器分配存儲的空間。監控和傳輸的寄存器數量,由GNU官方定義。比如在GNU提供的AARCH64 gdb說明中,其對org.gnu.gdb.aarch64.core的定義如下:
org.gnu.gdb.aarch64.core的定義

2.2.2 xxxGdb.c的實現

xxxGdb.c 中必須實現如下圖所示的接口。
xxxGdb.c 需要實現的接口
在xxxGdb.c中定義了兩個描述 xml 結構的全局變量,分別爲CoreXml和TargetXml的描述,這兩個描述類型都可以從GNU查詢到。
CoreXml的定義
TargetXml的定義
需要實現接口中的archGdbCoreXml和archGdbTargetXml就是分別返回這兩個結構的函數實現。
archGdbRegsGet和archGdbRegsSet分別用於返回寄存器結構的狀態,以及對寄存器結構中的狀態值進行設置,通過這兩個函數,就可以在IDE中監測和設置對應的寄存器值。
archGdbRegSetPc、archGdbRegGetPc和archGdbGetNextPc 是對PC指針的獲取和設置,其中archGdbRegSetPc和archGdbRegGetPc就是單獨對寄存器結構中的PC值進行設置和獲取。
archGdbGetNextPc是單步調試重點需要實現的邏輯。此段代碼邏輯中,需要針對異常分支、直接設置PC、函數返回等多種情況下,Next PC的邏輯進行考慮和實現。

2.2.3 xxxDbg.c的實現

xxxDbg.c 中必須實現如下圖所示的接口。
xxxDbg.c 的實現
archDbgAbInsert用於實現斷點插入的邏輯。斷點插入的實現思路是,在需要產生斷點的位置,替換一條斷點指令。這樣當程序運行到斷點處時,就會進入斷點異常,在斷點異常的處理流程中,向gdb-host發送寄存器狀態。
archDbgBpRemove 、archDbgBpPrefetch 和 archDbgBpAdjust 都是對斷點的通用處理,基本上各個架構實現的方式都類同。

3. RealEvo-IDE配置中需要修改的地方

此外,在RealEvo-IDE的安裝目錄“RealEvo\ide\tools\gdb”內需要根據具體的架構,預先創建一個gdbinit.txt文檔。
否則,在IDE中啓動gdb程序時,會出現異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章