基于Eclipse平台的嵌入式远程调试软件实现
2014-08-07康慕宁
王 爽,康慕宁
(西北工业大学计算机学院,西安710129)
基于Eclipse平台的嵌入式远程调试软件实现
王 爽,康慕宁
(西北工业大学计算机学院,西安710129)
传统嵌入式系统大多采用命令行打印的方式进行开发调试,导致开发周期延长。针对这个问题,基于Eclipse平台和CDT插件设计并实现了一套可视化的嵌入式远程调试软件。主机端的调试总控通过MI接口封装通用调试器GDB,按照DWARF调试信息格式提取目标文件中的调试信息,并通过RSP协议发送调试命令,目标机端的调试代理负责接收并处理调试命令。着重分析了调试总控的设计和调试代理的实现要点,最终实现了对MPC8270上目标程序的源码级远程调试。
嵌入式;调试代理;远程调试;GDB调试器
1 引 言
随着嵌入式软件开发规模的不断扩大,如何高效地对嵌入式软件进行调试成为系统开发中的一个难题。由于嵌入式系统本身的计算能力、存储能力、外设资源都非常有限,在嵌入式MCU上运行一个调试器是不太现实的。在很长一段时间内,开发人员大都使用串口打印输出到命令行的方式进行调试,这种调试手段严重延长了软件的开发周期,在主机端上的IDE进行远程调试逐渐成为一个发展趋势。远程调试采用主机/目标机交叉的方式进行,调试器运行在主机端,被调试程序运行在目标机端,主机端的调试器通过串口或网络与目标机通信,控制目标机上被调试程序的运行,实现对目标文件的调试。
GNU开源组织发布的GDB(GNU Debugger)是一个强大的通用程序调试工具[1],它对本地调试和远程调试都提供支持。GDB支持CLI(Command Line Interface)和MI(Machine Interface)两种外部调试工具接口。Eclipse是利用MI方法支持C语言源码级调试最好的开源工具[2],故在Eclipse平台的基础上使用CDT插件开发远程调试器图形前端,利用GDB/MI接口封装GDB,使图形前端能够和GDB相互通信,在目标机端搭建调试代理模块,最终构建了一个可视化的嵌入式远程调试软件,不仅提高了开发效率,而且减少了软件成本。
2 远程调试软件设计原理
嵌入式远程调试软件主要由主机端的调试器和目标机端的调试代理组成,主机调试器与调试代理通过远程调试通信协议RSP进行通信[3]。主机调试器按照DWARF调试信息格式提取目标文件中的调试信息,根据RSP协议把要发送的调试命令封装成数据包,通过通信接口如网口或串口发送给调试代理以及接收调试代理发送的调试信息数据包,并且在Eclipse图形界面上显示相应的调试信息。调试代理接收并解析用户的远程调试命令,根据调试命令控制被调试程序的运行,并且把调试信息封装成数据包发送给主机调试器。
CDT插件为Eclipse提供了C/C++程序的编辑、编译、运行及本地调试功能[4]。为满足嵌入式远程调试的需求,需要对Eclipse的调试模块进行功能扩展,使扩展后的CDT插件能够调用GDB对目标机上的被调试程序进行远程调试。主要扩展的部分如下:①调试器远程连接部分。远程连接目标机,首先需要配置远程调试信息,如:连接方式、目标机IP地址、端口号等,然后远程调试器利用配置信息连接调试代理,连接成功则建立调试会话,若遇异常则退出。②远程调试信息处理部分。根据远程调试时返回的调试信息格式进行信息解析、提取和存储,根据视图要求实时显示调试信息。③调试管理部分。接收图形界面中的配置信息,负责发送调试信息及调试命令至GDB。远程调试软件结构如图1所示。
图1 远程调试软件结构
3 远程调试软件关键技术
3.1 调试信息提取
调试信息是GCC编译器在编译时从源文件中收集的信息,包括文件名、函数名、函数参数、函数入口地址、变量名、变量类型、行号以及对应的地址等等,然后按照DWARF(Debugging With Attributed Record Formats)调试信息格式写入到目标文件中[5]。远程调试器在工作时能够从目标文件中提取调试信息,建立源代码和目标文件之间的对应关系。
调试信息主要分布在ELF文件中的以.debug_ *开头的节,其中.debug_info节和.debug_line节中的调试信息是关键信息,.debug_info节保存的内容是文件名信息、函数信息、变量信息以及类型信息等,.debug_line节保存的是机器指令地址和源文件行的对应信息。
DWARF最基本的描述实体为DIE(Debugging Information Entry)。每个DIE都有自己的标签(包含类型和一系列属性),类型以DW_TAG为前缀标记,属性以DW_AT为前缀标记。DIE以儿子兄弟树的结构存储,属性指向其他的DIE。DIE类型有:DW_TAG_compile_unit、DW_TAG_subprogram、DW_ TAG_formal_parameter、DW_TAG_variable、DW_TAG _pointer_type等。图2是.debug_info节的树形结构图。
图2 debug_info的树形结构
调试信息处理模块首先通过ELF文件头计算出.debug_info节和.debug_line节在目标文件中的位置,然后利用开源的libdwarf库(提供大量的API函数接口)对这两个节中的二进制码进行解析[6],从中提取调试信息。libdwarf库对每个DIE进行解析,根据DIE的类型分别进行处理,最后生成的调试信息分别存储在各自定义的结构体中。在所有的调试信息中,源程序行号与目标文件机器指令地址的对应关系是最重要的调试信息。该模块采用STL的Map映射模板类来实现这种对应关系,其定义如下:Map(UINT,UINT)mapAddrToFileLine,既可以完成机器指令地址到行号的对应,又可以完成行号到机器指令地址的对应。
3.2 调试代理设计
调试代理作为目标机上运行的一段程序,接收和处理主机调试器的调试请求,并向主机调试器反馈调试信息[7]。为了使调试代理不占用过多的目标机资源,同时提高调试代理的执行效率,目标机端的调试代理采用模块化、层次化设计,调试代理的基本结构如图3所示。
调试代理根据远程调试软件的功能分为以下几个模块:
图3 调试代理结构
(1)异常处理模块:当被调试程序遇到异常暂停执行时,调试代理获得CPU的控制权,处理完异常之后调试代理交出CPU控制权,目标文件继续运行。
(2)功能执行模块:主要负责执行主机调试器发送的调试命令,包括内存值读写、寄存器值读写、断点设置、单步执行等命令,将执行结果发送给调试通信模块。
(3)调试通信模块:根据调试通信协议RSP对发送过来的调试命令进行解析和封装,并且对数据进行验证。
(4)通信接口模块:主要负责与主机调试器的通信,接收调试命令,并返回调试结果。为了用户方便使用,提供多种通信接口,如串口、USB、网口等,通信接口模块中有相应的接口驱动模块,用来屏蔽不同的通信方式。
(5)功能扩展模块:为以后扩展调试代理功能提供方便。
根据上述要求编写调试代理程序,下面详细介绍一下调试代理的实现过程:
(1)首先把主机端的调试命令预先注册到异常向量表中,每个调试命令都对应唯一的标识、处理函数指针等[8]。之后调试代理等待主机端的调试命令,主机调试器发出调试命令后,系统会将CPSR(当前程序状态寄存器)的值自动修改,从而调试代理知道命令类型。获得调试命令后,调试代理首先解析出标识号,然后查表获取处理函数的入口地址,保存现场,调用处理函数。
(2)进入异常处理函数后,调试代理通过通信接口接收主机调试器发送的命令,主要包括调试过程中的断点设置,单步执行,寄存器值读写,内存值读写,变量值读写,终止等功能。调试代理获得某个命令后,便执行相应的调试动作。执行单步命令之后恢复异常之前的寄存器值,使目标文件从异常处继续运行。
(3)调用调试通信模块,调试通信模块按照远程调试信息规定的格式对数据进行解析、封装,接收来自通信接口的数据包,解析出调试命令,通过功能执行模块进行相应的处理。执行完调试命令后,将命令的执行结果封装成数据包,再通过RSP通信协议发送给主机调试器。
3.3 主要调试功能设计
远程调试软件提供的调试功能有:连接目标机、断点设置与删除、单步、变量查看与修改、寄存器读写、内存读写等。断点设置和变量查看是调试器控制程序执行的基本手段。下面详细介绍断点设置和变量查看的设计。
(1)断点设置
断点从实现方式上可以分为两种:硬件断点和软件断点。硬件断点是依赖硬件实现的,具有一定的局限性;而软件断点具有通用性。软件断点是将设置断点处原有的指令替换为产生异常的指令,当目标机运行到此断点处时,主机调试器会捕获到异常,目标机暂停执行,由调试代理接管对目标文件的控制。
断点设置的实现过程如下:首先,在源代码中的某一行处设置断点时,把断点所在行的信息保存在自定义的双向链表结构中;其次,根据当前的源文件名和行号,通过查询目标文件的符号表获得源文件名加行号所对应的目标代码地址;第三,给目标机发送写内存指令,在断点处写上异常指令;第四,中断产生后,恢复预先保存的指令代码,此时调试者可以通过调试命令查看目标文件的上下文信息。
(2)变量操作
调试器的变量操作包括局部变量和全局变量的查看和修改,即从内存中读取数据或者把数据写到相应的内存单元中。全局变量存放在数据区,可以直接访问其内存地址;而局部变量存放在堆栈区,其地址是变化的,因此需要对目标文件进行解析,找到变量的内存地址。
变量在DWARF调试规范中的标签是DW_TAG_variable。DW_TAG_variable的属性包括变量名DW_ AT_name、源文件名DW_AT_decl_file、行号DW_AT_ decl_line、变量类型DW_AT_type、存放位置DW_AT_ location等。全局变量用DW_AT_external属性标识[9],其DW_AT_location属性内容为操作码DW_OP _addr,操作数是全局变量的内存地址。局部变量的DW_AT_location属性内容为操作码DW_OP_fbreg,操作数是相对所在函数的偏移量,即局部变量存储在以其所在函数的帧栈基地址开始偏移DW_OP_ fbreg值处,函数属性DW_AT_frame_base指定函数的当前帧栈基地址。因此,读取全局变量仅向调试代理发送变量地址,而读取函数局部变量首先向调试代理发送读取函数帧栈基址寄存器的命令,将调试代理返回的结果与局部变量的偏移量相加形成局部变量内存地址,然后再向调试代理发送变量地址。
4 运行结果与验证
嵌入式远程调试软件中主机调试器运行在Windows XP上,目标机处理器为MPC8270。对于被调试的程序首先使用GCC编译生成目标文件,主机调试器通过网口或串口连接到目标机的调试代理,在主机端搭建一个FTP服务器,目标机端通过FTP命令将目标文件下载到目标机[10],同时将连接信息返回给调试图形界面,以目标机视图的形式进行展示。在主机端设置断点开始调试运行,调试代理会中断目标文件的正常执行,等待主机的调试命令。主机端发送调试命令,对运行在目标机端的目标文件进行远程调试,操作过程与本地调试操作一样。通过Eclipse的各个视图可以查看和设置内存、变量、寄存器等信息。图4显示的是调试过程中调试系统透视图。
图4 调试系统透视图
5 结束语
通过对嵌入式远程调试的原理深入研究,利用Eclipse GDB/MI接口封装GDB和在目标机端搭建调试代理,设计并实现了基于Eclipse平台的可视化嵌入式远程调试软件。远程调试软件可以完成本地调试器所具备的功能,例如内存值读写、寄存器值读写、断点设置、单步执行等等,不但可以方便有效地帮助开发人员调试嵌入式程序,提高开发效率,而且大大降低项目的开发成本。由于该软件是在Eclipse插件的基础上实现的,因此它具有可扩展性,、可移植性强。设计的嵌入式远程调试软件只是针对单处理器,对多处理器的支持是下一步的研究重点。
[1]Richard Stallman,Roland Pesch,Stan Shebs,et al.Debuggingwith GDB:The GNU Source-Level Debugger,Tenth Edition[M].Boston:Free Software Foundation,2011.
[2]Jeong-Hoon Ji,Gyun Woo,Hyung-Bae Pak.Design and Implementation of Retargetable Software Debugger based on GDB[C].Third 2008 International Conference on Convergence and Hybrid Information Technology:737-740.
[3]Jeremy Bennett.Howto:GDB Remote Serial Protocol[EB/OL].Embecosm,2008[2013].http://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-serverean4-issue-2.html.
[4]Michael Galpin.Developing applications using the Eclipse C/C++Development Toolkit[EB/OL].IBM developer Works,2007[2013].http://www.ibm.com/developerworks/opensource/library/os-eclipse-stlcdt/.
[5]DWARF Standards Committee.DWARF Debugging Information Format Version 3[S].Free Standards Group,2005.
[6]龚兰兰,刘晓升,朱巧明.远程调试系统的关键技术分析[J].计算机软件与理论,2010,27(10):258-261.
[7]温丽娜,谢彬,李连云.远程开发环境中的目标机代理设计[J].计算机工程,2007,33(2):277-279.
[8]李红卫.嵌入式远程调试工具的研究与实现[J].微计算机信息,2009,25(1-2):87-89.
[9]张君毅,李洪威,桑钊,等.基于Eclipse的开发环境中调试器设计与实现[J].现代电子技术,2009(6):53-56.
[10]李杰.Linux环境下FTP系统的设计与实现[D].长春:吉林大学,2012.
Im plementation of Embedded Remote Debugging Software Based on Eclipse Platform
WANG Shuang,KANG Mu-ning
(School of Computer Science,Northwestern Polytechnical University,Xi’an 710129,China)
In order to solve the problem of long development cycle caused by the traditional embedded system,which mostly uses the command-line print for developing and debugging,the visual embedded remote debugging software based on the Eclipse platform and the CDT plug is designed and implemented in this paper.The debuging control software encapsulates the general cross debugger GDB through MI interface,analyzes debugging information of object file according to DWARF debugging information standard,and sends debugging commands via RSP.The debugging agent receives and handles debugging commands.The paper emphasizes on design and implementation of debugging control software and debugging agent,and the source level remote debugging for the target program running on MPC8270 is achieved.
Embedded;Debug Agent;Remote Debugging;GDB Debugger
10.3969/j.issn.1002-2279.2014.03.016
TP311
:A
:1002-2279(2014)03-0056-04
王爽(1989-),女,河南新乡人,硕士研究生,主研方向:嵌入式系统及应用。
2013-11-14