嵌入式操作系统的调试(3)
时间:2007-02-17 来源:PHP爱好者
深入话题
传统的调试方法可概括为如下过程:设断点--程序暂停--观察程序状态--继续运行。被调试的如果是实时系统,即使调试器支持批处理命令避免了用户输入命令、观察结果带来的延迟,它与目标系统之间的通信也完全可能错过对目标平台外设信号的响应。于是,针对某些调试器(如GDB)提供的监视点(trace point)这一特殊调试手段,目标方的插桩在原有的基础上被改进,称为代理(agent)。调试时用户首先在调试器设置监视点,以源代码表达式的形式指定感兴趣的对象名。为了减少代理解析表达式的工作,调试器将表达式转换为简单的字节码,传送至代理。程序运行后命中监视点、唤醒代理,代理根据字节码记录用户所需数据存入特定缓冲区(不仅仅是表达式的最终结果,还有中间结果),令程序继续运行;这一步骤无需与调试器通信。当调试器再度得到控制时,就可以发出命令,向代理查询历次监视记录。较之于插桩,代理增加了对接受到的字节码的分析模块,相应的目标代码体积只有大约3K字节;当然,监视记录缓冲区也要占用目标平台的存储空间,不过缓冲区的大小可在代理生成时由用户决定。总之,这一改进以有限的目标系统资源为代价,为实时监视提供了一个低成本的可行方案。
调试并不仅仅意味着设断点--程序暂停--观察--继续这一过程,往往还需要profiling、跟踪(trace)等多种手段,而现代微处理器的技术进步却为这些调试手段的实行带来了困难。以跟踪为例,其目的无非是记录真实的程序运行流;可现代处理器指令缓存都集成于芯片内(RISC处理器尤为如此),运行指令时"取指"这一操作大多在芯片内部针对指令缓存进行,芯片外部总线上只能观察到多条指令的预取(prefetch),预取的指令并不一定执行(由于跳转等原因);另外,指令往往经过动态调度后在流水线中乱序执行,如何再现其原始顺序也是个问题。解决方案大致有以下三种:
1.有的处理器除了正常运行外,还能以串行方式运行,所有的取指周期都可呈现于片外总线(相当于禁用缓存与流水线)。这样一来,跟踪容易多了,处理器性能也大大降低了,根本不适用于实时要求严格的系统。
2.编译器自动在指定的分支及函数出入口插入对特定内存区域的写指令(与gprof等profiling工具采用的手段类似),它们都是不通过缓存而直接向内存写的,这就能反映于芯片外总线从而被外接的逻辑分析仪记录,最终由主机端的调试工具分析并结合符号表重构程序流。这种方法虽被广泛使用,但毕竟是干扰式的(intrusive),对系统性能也有影响。
3.像上文所述的片上调试那样,也有处理器在片内附加了跟踪电路,收集程序流运行时的"不连贯"(discontinuities)信息(分支和异常处理的跳转目的及源地址等),压缩后送至特定端口,再由逻辑分析仪捕获送至主机端调试工具重构程序流。该方案对系统性能影响最小。
总之,处理器厂家提供集成于片内的调试电路为高档嵌入式系统开发提供各种非干扰式的调试手段早已是大势所趋。为了解决该领域标准化的需要,一些处理器厂家、工具开发公司和仪器制造商于1998年组成了Nexus 5001 Forum,这是一个旨在为嵌入式控制应用产生和定义嵌入式处理器调试接口标准的联合组织,以前的名称是Global Embedded Processor Debug Interface Standard Consortium(全球嵌入式处理器调试接口标准协会)。Nexus现在有24个成员单位,包括创始成员Motorola、Infineon Technologies、日立、ETAS和HP等公司。该组织首先处理的是汽车动力应用所需要的调试,现在已发展成为调试数据通信、无线系统和其他实时嵌入式应用的通用接口。
参考文献
MPC860 PowerQUICC User's Manual MOTOROLA
http://www.vas-gmbh.de/software/mpcbdm/
http://www.metrowerks.com/tools/documentation/embedded/zenofbdm
http://www.redhat.com/support/wpapers/cygnus_heinsenberg/trace.html
http://www.ednmag.com/reg/2000/05112000/10tt.htm
作者简介
熊竞,任职于中科院计算所嵌入式系统软件组。主要从事开发嵌入式操作系统的仿真器、调试器及集成开发环境。您可以通过电子邮件 [email protected]与他联系。
php爱好者站 http://www.phpfans.net PHP|MySQL|javascript|ajax|html.
传统的调试方法可概括为如下过程:设断点--程序暂停--观察程序状态--继续运行。被调试的如果是实时系统,即使调试器支持批处理命令避免了用户输入命令、观察结果带来的延迟,它与目标系统之间的通信也完全可能错过对目标平台外设信号的响应。于是,针对某些调试器(如GDB)提供的监视点(trace point)这一特殊调试手段,目标方的插桩在原有的基础上被改进,称为代理(agent)。调试时用户首先在调试器设置监视点,以源代码表达式的形式指定感兴趣的对象名。为了减少代理解析表达式的工作,调试器将表达式转换为简单的字节码,传送至代理。程序运行后命中监视点、唤醒代理,代理根据字节码记录用户所需数据存入特定缓冲区(不仅仅是表达式的最终结果,还有中间结果),令程序继续运行;这一步骤无需与调试器通信。当调试器再度得到控制时,就可以发出命令,向代理查询历次监视记录。较之于插桩,代理增加了对接受到的字节码的分析模块,相应的目标代码体积只有大约3K字节;当然,监视记录缓冲区也要占用目标平台的存储空间,不过缓冲区的大小可在代理生成时由用户决定。总之,这一改进以有限的目标系统资源为代价,为实时监视提供了一个低成本的可行方案。
调试并不仅仅意味着设断点--程序暂停--观察--继续这一过程,往往还需要profiling、跟踪(trace)等多种手段,而现代微处理器的技术进步却为这些调试手段的实行带来了困难。以跟踪为例,其目的无非是记录真实的程序运行流;可现代处理器指令缓存都集成于芯片内(RISC处理器尤为如此),运行指令时"取指"这一操作大多在芯片内部针对指令缓存进行,芯片外部总线上只能观察到多条指令的预取(prefetch),预取的指令并不一定执行(由于跳转等原因);另外,指令往往经过动态调度后在流水线中乱序执行,如何再现其原始顺序也是个问题。解决方案大致有以下三种:
1.有的处理器除了正常运行外,还能以串行方式运行,所有的取指周期都可呈现于片外总线(相当于禁用缓存与流水线)。这样一来,跟踪容易多了,处理器性能也大大降低了,根本不适用于实时要求严格的系统。
2.编译器自动在指定的分支及函数出入口插入对特定内存区域的写指令(与gprof等profiling工具采用的手段类似),它们都是不通过缓存而直接向内存写的,这就能反映于芯片外总线从而被外接的逻辑分析仪记录,最终由主机端的调试工具分析并结合符号表重构程序流。这种方法虽被广泛使用,但毕竟是干扰式的(intrusive),对系统性能也有影响。
3.像上文所述的片上调试那样,也有处理器在片内附加了跟踪电路,收集程序流运行时的"不连贯"(discontinuities)信息(分支和异常处理的跳转目的及源地址等),压缩后送至特定端口,再由逻辑分析仪捕获送至主机端调试工具重构程序流。该方案对系统性能影响最小。
总之,处理器厂家提供集成于片内的调试电路为高档嵌入式系统开发提供各种非干扰式的调试手段早已是大势所趋。为了解决该领域标准化的需要,一些处理器厂家、工具开发公司和仪器制造商于1998年组成了Nexus 5001 Forum,这是一个旨在为嵌入式控制应用产生和定义嵌入式处理器调试接口标准的联合组织,以前的名称是Global Embedded Processor Debug Interface Standard Consortium(全球嵌入式处理器调试接口标准协会)。Nexus现在有24个成员单位,包括创始成员Motorola、Infineon Technologies、日立、ETAS和HP等公司。该组织首先处理的是汽车动力应用所需要的调试,现在已发展成为调试数据通信、无线系统和其他实时嵌入式应用的通用接口。
参考文献
MPC860 PowerQUICC User's Manual MOTOROLA
http://www.vas-gmbh.de/software/mpcbdm/
http://www.metrowerks.com/tools/documentation/embedded/zenofbdm
http://www.redhat.com/support/wpapers/cygnus_heinsenberg/trace.html
http://www.ednmag.com/reg/2000/05112000/10tt.htm
作者简介
熊竞,任职于中科院计算所嵌入式系统软件组。主要从事开发嵌入式操作系统的仿真器、调试器及集成开发环境。您可以通过电子邮件 [email protected]与他联系。
php爱好者站 http://www.phpfans.net PHP|MySQL|javascript|ajax|html.
相关阅读 更多 +