GDB是GNU开源组织发布的一个强大的UNIX下程序调试工具。SylixOS中除Lite版本外,均可以实现GDB调试功能。 GDB能够对C和C++程序进行调试,它使用户能在程序运行时观察程序的内部结构和内存的使用状况。如下是GDB所提供的一些功能:数组
GDB由gdb-server和gdb-host组成。 目标板使用gdb-server来启动已经编译好的代码,执行断点、单步等调试动做,同时经过网络、串口等反馈调试须要的信息给gdb-host。 宿主机上运行gdb-host,解析gdb-server传来的信息,同时,发送断点、单步等动做给目标板。网络
在SylixOS中,gdb-server的主要通讯流程和网络通讯框架,已经在Base中实现,代码位置以下图所示。 架构
这部分代码逻辑中,已经完成和gdb-host的通讯逻辑。当在RealEvo-IDE中的Debug界面,进行单步,运行到指定行,全速运行等操做时,gdb-host实际经过对应架构的xxxx-sylixos-elf-gdb.exe工具与板卡内的gdb-server进行通讯。框架
在每一个具体架构中,都存在dbg目录,该目录下对应有xxxDbg.c和xxxGdb.c文件,以及xxx_gdb.h文件,以下图所示。ide
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的定义以下:工具
xxxGdb.c 中必须实现以下图所示的接口。fetch
在xxxGdb.c中定义了两个描述 xml 结构的全局变量,分别为CoreXml和TargetXml的描述,这两个描述类型均可以从GNU查询到。
指针
须要实现接口中的archGdbCoreXml和archGdbTargetXml就是分别返回这两个结构的函数实现。 archGdbRegsGet和archGdbRegsSet分别用于返回寄存器结构的状态,以及对寄存器结构中的状态值进行设置,经过这两个函数,就能够在IDE中监测和设置对应的寄存器值。 archGdbRegSetPc、archGdbRegGetPc和archGdbGetNextPc 是对PC指针的获取和设置,其中archGdbRegSetPc和archGdbRegGetPc就是单独对寄存器结构中的PC值进行设置和获取。 archGdbGetNextPc是单步调试重点须要实现的逻辑。此段代码逻辑中,须要针对异常分支、直接设置PC、函数返回等多种状况下,Next PC的逻辑进行考虑和实现。调试
xxxDbg.c 中必须实现以下图所示的接口。
archDbgAbInsert用于实现断点插入的逻辑。断点插入的实现思路是,在须要产生断点的位置,替换一条断点指令。这样当程序运行到断点处时,就会进入断点异常,在断点异常的处理流程中,向gdb-host发送寄存器状态。 archDbgBpRemove 、archDbgBpPrefetch 和 archDbgBpAdjust 都是对断点的通用处理,基本上各个架构实现的方式都类同。
此外,在RealEvo-IDE的安装目录“RealEvo\ide\tools\gdb”内须要根据具体的架构,预先建立一个gdbinit.txt文档。 不然,在IDE中启动gdb程序时,会出现异常。