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-host的通信逻辑。当在RealEvo-IDE中的Debug界面,进行单步,运行到指定行,全速运行等操作时,gdb-host实际通过对应架构的xxxx-sylixos-elf-gdb.exe工具与板卡内的gdb-server进行通信。

2.2 ARCH需要实现的内容

在每个具体架构中,都存在dbg目录,该目录下对应有xxxDbg.c和xxxGdb.c文件,以及xxx_gdb.h文件,如下图所示。

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的定义如下:

2.2.2 xxxGdb.c的实现

xxxGdb.c 中必须实现如下图所示的接口。

在xxxGdb.c中定义了两个描述 xml 结构的全局变量,分别为CoreXml和TargetXml的描述,这两个描述类型都可以从GNU查询到。


需要实现接口中的archGdbCoreXml和archGdbTargetXml就是分别返回这两个结构的函数实现。
archGdbRegsGet和archGdbRegsSet分别用于返回寄存器结构的状态,以及对寄存器结构中的状态值进行设置,通过这两个函数,就可以在IDE中监测和设置对应的寄存器值。
archGdbRegSetPc、archGdbRegGetPc和archGdbGetNextPc 是对PC指针的获取和设置,其中archGdbRegSetPc和archGdbRegGetPc就是单独对寄存器结构中的PC值进行设置和获取。
archGdbGetNextPc是单步调试重点需要实现的逻辑。此段代码逻辑中,需要针对异常分支、直接设置PC、函数返回等多种情况下,Next PC的逻辑进行考虑和实现。

2.2.3 xxxDbg.c的实现

xxxDbg.c 中必须实现如下图所示的接口。

archDbgAbInsert用于实现断点插入的逻辑。断点插入的实现思路是,在需要产生断点的位置,替换一条断点指令。这样当程序运行到断点处时,就会进入断点异常,在断点异常的处理流程中,向gdb-host发送寄存器状态。
archDbgBpRemove 、archDbgBpPrefetch 和 archDbgBpAdjust 都是对断点的通用处理,基本上各个架构实现的方式都类同。

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

此外,在RealEvo-IDE的安装目录“RealEvo\ide\tools\gdb”内需要根据具体的架构,预先创建一个gdbinit.txt文档。
否则,在IDE中启动gdb程序时,会出现异常。