Board logo

标题: C语言级单步调试功能的实现 [打印本页]

作者: 520503    时间: 2015-5-4 23:33     标题: C语言级单步调试功能的实现

关键字:C语言   单步调试   BWDSP  
BWDSP是一款我国自主研发的多核高性能通用DSP。BWDSP的体系结构、指令集、配套基础软件全部由中电38所自主设计开发。BWDSP的配套基础软件包括汇编器、编译器、调试器、集成开发环境、芯片模拟器等等。BWDSP芯片的调试器软件包括主机调试器软件和调试链接服务软件两部分。调试链接服务软件运行于ICE(In Circuit Emulator)上,起到主机与芯片之间通信互联的功能。而主机调试器软件是调试系统的核心,负责解析用户命令、分析调试信息、管理可执行文件、管理断点(和观察点)、单步调试控制等等[1]。BWDSP的调试系统支持汇编级调试和C语言级调试。在开发BWDSP芯片调试系统的C语言单步调试功能的过程中,研发人员分析了国内外类似工作的可取之外和不足之处,自主创新开发出实现方案。
国内已经陆续有研究机构自主创新开始调试系统的研发工作[2-7],但这些工作在实现C语言单步调试方面都存在一些不足。文献[2-3]中的单步调试功能是汇编语言级的单步调试。文献[7]中的调试系统虽然实现了C语言级单步调试功能,但并未充分考虑到C语言一行代码可能的复杂性,只能实现简单C语言代码的单步调试功能。本文提出的方案充分考虑了C语言单步调试需要面临的问题,可以实现任意复杂程序的C语言代码行的单步调试功能。本方案原理简单,容易理解,并经过大量BWDSP芯片调试过程的检验,已经证明了其正确性。

1。单步调试功能简介

单步调试指以源代码行为单位对被调试程序的运行进行控制的调试功能。单步调试不需要用户显式地设置断点,可以控制程序运行一个或若干个代码行。通过这种方式,用户可以结合变量查看、堆栈查看、观察点等调试功能,把潜在的程序错误定位至某个代码行。单步调试功能一般分为两大类:汇编级单步调试功能和源代码级单步调试功能。汇编级单步调试功能指单步调试控制运行的单位是汇编语言的代码行。源代码级单步调试指单步调试控制运行的单位是高级语言源代码中的代码行。每类单步调试功能一般又包括三种:跳入、跳过、跳出。

对于汇编级单步调试,三种单步调试功能的实现较为简单,其功能概述如下:
跳入调试功能控制被调试程序运行至当前代码行中调用的函数内部。若当前代码行中无函数调用,则控制被调试程序运行完当前代码行。

跳过指控制被调试程序运行完当前代码行。若当前代码行中有函数调用,则控制被调试程序执行完该函数调用并继续运行完当前代码行。

跳出指控制被调试程序运行至当前函数的返回地址处。

对于高级语言如C语言,其三种单步调试功能从总体概念上和汇编级单步调试功能类似。但由于C语言一行代码经编译后生成一段汇编指令,且一行代码中的语句可能非常复杂,其单步调试功能相对于汇编级单步调试更为复杂。C语言单步调试功能的实现要面对如下几个问题:

1.程序当前PC(Program Counter,指程序地址)并不一定在一行代码的最开始处,而有可能在一行代码生成的一段汇编指令的中间位置。用户有可能先通过汇编级调试功能使PC停在C语言代码行的中间位置,然后再进行C语言级单步调试。
2.一行代码中可能不止一个函数调用。C语言中一行代码中可以有任意多个函数调用。
3.一行代码可能有多个return语句。C语言中,一行代码中可以写任意长的代码,其中可能包含若干个条件控制语句(if…else…),每种条件下都可能有一个return语句,程序有可能从其中任意一个return语句处从本函数返回。
4.一行代码可能有多个出口。若代码行处于循环之中,则代码行中每个break(或continue)语句都可以跳出本行。若代码行中有多个break(或continue)语句,则程序可能从其中任意一个位置离开本行。
5.一行代码中的出口有可能是条件跳转的出口,程序并不一定从该出口跳出。条件跳转根据运行时的具体情况来判断是否需要跳转,有可能跳转,也有可能不跳转。
6.函数调用有可能以函数指针的方式实现。C语言中定义有函数指针,通过函数指针进行函数调用同样是函数调用的一种方式,跳入功能的实现必须考虑这种情况。
7.程序的执行可能不是简单的顺序执行。用户可以把一个完整的循环写到一行代码中,因此程序流可能不是顺序执行的,有可能回到本代码行中已经执行过的某个程序位置继续执行。C语言级单步调试功能的实现不能依赖于程序流的顺序执行。
8.一行代码有可能没有下一行代码。如一行代码位于函数体或源文件的最后一行,则该行代码是没有下一行代码的。运行完该行代码后程序流只会返回到上一层函数,或跳转至本函数中其他位置。
9.单步调试过程中可能由于其他原因使调试过程提前结束。若用户设置了断点或观察点,单步调试过程中可能引起这些断点(或观察点)的触发,使单步调试过程提前结束。
由于C语言单步调试功能面临这些复杂的问题,因此C语言单步调试功能的实现远比汇编级单步调试功能的实现要复杂。3.3跳入
跳入调试功能使程序可以进入代码行中调用的函数内部。若程序在当前代码行中的执行过程中没有遇到函数调用,则执行完本代码行即完成单步调试功能,此时其调试功能与跳过单步调试类似。显然,实现单步跳入调试功能需要在L、F、R、N处都设置临时断点。
对于F类出口中的第②类函数调用(寄存器函数调用),同样需要在函数调用指令处设置临时断点。当该临时断点触发时,控制程序进行一次汇编级指令行单步,使程序进入调用函数。该方法可以解决第6个问题。


/2015/CLanguageStepDebugging05.JPG"

图3 跳入单步调试功能实现流程图



由于本方案在所有函数调用处都设置了断点,所以程序会停止在执行过程中的第一个函数调用出口。调试行为表现为程序会跳入执行过程中遇到的第一个函数。
第1节中介绍的所有问题都对跳入单步调试功能有影响,而本方案可以解决所有9个问题。
跳入调试功能的实现流程如图3所示。

3.4 实验结果
BWDSP芯片配套调试系统的C语言单步调试功能按照本文介绍的方案实施。开发人员以任意复杂的C语言代码行在各种复杂的调试场景下对单步调试功能进行测试,调试系统均可按单步调试预定义的功能完成调试过程。目前,在BWDSP芯片的模拟器、编译器、操作系统开发过程中,均已经在项目组内部试用本调试器进行C语言级调试。经过反复测试、试用、修改,本方案已经证实是一个健壮的实施方案,可以实现任意复杂C语言代码行的单步调试功能。

总结
本文介绍了BWDSP芯片调试系统中C语言单步调试功能的实现方案。该方案充分研究了C语言一行源代码中可能对单步调试功能产生影响的各种情况,充分考虑了C语言代码行的复杂性,可以实现任意复杂C语言代码行的单步调试功能。经BWDSP芯片调试过程的验证,证实了本方案的有效性。


[1]黄光红,刘冠南。可配置多核处理器的调试器模块化分层设计[J]。单片机与嵌入式系统应用,2014,14(7):13-15。
[2]向征。基于C30的嵌入式计算机自主调试环境的建立和软件设计[J]。微电子学与计算机,1999,3,18-20,56。
[3]文跃荣。基于UART的电能芯片在线调试设计[D]。湖南大学,2012。
[4]刘晓升,王宜怀。HC08系列微控制器在线调试的关键技术分析[J]。计算机工程与设计,2009,30(3),532-535。
[5]龚兰兰,刘晓升,朱巧明。远程调试系统的关键技术分析[J]。计算机应用与软件,2010,27(10),258-261。
[6]梁泉。嵌入式系统交叉调试器的设计与实现[D]。电子科技大学,2008。
[7]赵民栋。嵌入式软件集成开发环境中调试器的设计与实现[D]。西北工业大学,2004。





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0