多核软件调试向传统方法提出挑战

Version 1

    对多核系统软件进行调试时,嵌入式设计人员必须突破传统 “一次解决一个 bug”的方法。

    笔者:Doug Gaff
    软件开发人员对于传统的调试流程非常熟悉:首先打开调试对话,在断点处中止应用,逐句通过代码,检查数据,找出 bug,编译(build),而后再次重复这些步骤。所有的软件开发环境均提供这些基本功能。但这种循环过程以及大量实施该方法的工具每次仅能对一项问题进行调试。
    现在,我们已经进入了多核时代。通常,“多核”是指一个芯片, 其中包含了一个以上的可执行代码的逻辑设备( 例如, 多个处理器、处理器与数字信号处理器(DSP)、处理器与现场可编程门阵列(FPGA))。同时,它也可指在一个目标板(target board)上的多个处理器。对于构建开发工具的企业而言,多核在理论上应该是对现有使用方法的扩展。毕竟,设备软件开发工具已经解决了大量的“多个”:多对象、多处理器、多流程、多线程、多操作系统、多调试接口、多调试引擎,甚至多种编程语言。
    实际上,利用一个开发工具同时处理这么多截然不同的 “调试实体”是非常困难的。不同的操作系统通常需要使用不同的调试引擎,如 GDB 或厂商专有调试引擎。此外,它们还需要使用包括网络或 JTAG 在内的不同的调试连接。某些调试引擎仅可支持几种特定的处理器。而另一些调试器则主要是针对通过调试软件访问芯片的裸机而设计的,在很多情况下,这类调试器无法使用操作系统调试代理对应用进行调试。随着嵌入式设备特性的日益丰富,开发及调试这些设备软件所需的工具也层出不穷。
    通用框架
    为解决以上难题,需要制定通用的框架,以使不同厂商的多套开发解决方案之间实现互操作。令设备软件开发商和工具厂商感到欣喜的是,目前这一框架已经问世,即: Eclipse(www.eclipse.org)。Eclipse 不仅是开放源代码社区,同时还将开放源代码软件项目收集在一起,从 Java 开发到软件测试基础设施,再到业务报告生成,它所提供的内容包罗万象。而 Eclipse 最重要的功能则是创建框架和工具,使企业能够构建基于高端 Eclipse 技术的商用产品与解决方案。
    Eclipse技术可支持当前使用的所有开发语言, 包括 J a v a 、C / C++、Perl、Ruby、Fortran,乃至 COBOL。Eclipse 中最出众的两个语言项目是 Java 开发工具(JDT)与 C/C++ 开发工具(CDT)。二者具备丰富的特性,来支持上文提到的“编辑-编译-调试”循环过程,这些特性包括:具备代码高亮与完成功能的编辑器、代码浏览与重构(refactoring)、托管编译(managed build)以及调试功能。
    11.JPG
    然而,与多核调试最为密切相关的则是,这两种以及其它语言开发项目均能够在称为 Eclipse 平台调试模型的框架上构建各自的调试器。该框架为调试器提供了通用构建模块,使得调试器看上去如同内存、寄存器以及表达式一样;其调试结构简明,可显示流程、线程,以及栈帧(stack frame);针对开始、停止、步进和断点运行控制活动;并具备用于启动调试对话的推出机制。该框架经过扩展后,能够与多种调试引擎配合使用。
    目前,已有多家构建 Eclipse 高端技术商用产品的设备软件开发商意识对该框架进行进一步定制的必要性。这些企业于 2005 年 6 月共同启动了一项名为设备调试(Device Debugging)的 Eclipse 项目(www.eclipse.org/dsdp/dd),其成员包括开发工具厂商、操作系统厂商,以及半导体制造商。该项目致力于为设备软件开发构建增强型调试模块、应用编程接口(API),以及能够放大 Eclipse 平台的视图。时至今日,设备调试(Device Debugging)项目已将现有 Eclipse 调试模块发展成为更具通用性并可定制的一系列接口。这些接口可满足多套商用调试解决方案范围广泛,且具有多样性的要求。
    为实现 Eclipse 的定制化,该项目主要从以下三方面扩展 Eclipse 平台调试接口:
    具备定制调试器行为的灵活调试元素结构
    调试器对内容进行查看,并更新完全由调试引擎驱动的策略
    用户界面(UI)与调试引擎之间完全异步交互
    首先,灵活调试元素结构使得调试引擎得以突破通常用于主机软件开发中的 “流程-线程-堆栈”结构。在设备软件开发中,尤其是在多核环境下,处理器类型、操作系统,以及调试连接共同决定了呈现在开发人员面前的结构。举例来说,请思考任意一个具备多个处理器以及其它设备的目标板(参见图 1)。
    该目标板具有一个现场可编程门阵列(FPGA),以及包含两个处理器内核与一个 DSP 的片上系统(SoC)设备。在采用灵活调试结构的综合开发工具中,开发人员将看到如图 2 所示的调试布局。该范例使用了多个调试引擎,可能一个用于处理器,一个用于 DSP,而另一个则用于 FPGA。每种调试引擎都代表了连接类型和设备的可调试环境。这种定制化功能还能够在结构中的不同节点上更改调试器行为的含义。例如,当选择流程时点击 Go(进行)按钮,将重新开始这一流程及其所有线程。而在某个线程上点击 Go(进行)或 Step(步进)按钮,则调试引擎将仅作用于该线程,而其它线程则保持当前的运行或停止状态不变。
    其次,新型 Eclipse 调试模型接口使调试引擎能够对内容进行完全定制,并更新 Eclipse 不同调试器视图的策略(如,内存、寄存器、局部,以及表达式)。该功能非常重要,因为不同的调试引擎能够提供处理器资源不同级别的可视性,并对这些资源进行控制。例如,向目标处理器提供 JTAG 连接的调试引擎通常能够实现处理器硬件寄存器更高的可用性。因此,当与该调试引擎连接时,开发人员能够看到 Register(寄存器)视图,来反映其详情(例如,位域(bit field)描述与控制、系统寄存器,以及协处理器寄存器)。由于在嵌入式目标处理器上的内存与寄存器访问为实时操作,因此新型调试模型接口可使调试引擎控制内容更新的方式与时间。
    最后,新的接口使得 GUI 与调试引擎之间实现完全异步交互,从而提高调试器的性能和响应能力。下文的示例对完全异步交互的优势进行了完美诠释。想像一下,正在进行调试的应用中包含了多个大型数据结构,而开发人员在逐句通过代码时将对这些结构进行检查。开发人员将这些数据结构放在 Expression(表达式)视图下,并同时监控部分关键的处理器寄存器。
    开发人员逐句通过代码时,所有的数据都必须在各个视图中进行更新,这将极大地降低整体步进速度,使人感到烦躁。而通过实现 GUI 与调试引擎的异步交互,并允许引擎控制视图更新,调试引擎便能够中断视图刷新,同时用户可迅速逐句通过代码。当用户暂停时,则能够对视图进行刷新。
    对 Eclipse 平台所做的这些改进将作为临时 API 发布于今年 6 月推出的 Eclipse 3.2 中。这一可定制的调试框架为开发人员提供了增强的多核调试体验。在 Eclipse 中,多个调试引擎可同时与多个对象进行交互,共享调试器视图,并提供稳定的用户体验。借助这一全新框架,工具厂商可构建能够充分发挥其核心能力(如处理器架构、操作系统和硬件调试连接方法)的调试解决方案,同时实现多套解决方案间的互操作。
    22.JPG
    虽然这些功能为多核支持提供了良好的开端,但仍需进行大量的工作来实现多个调试引擎的同步以及潜在协同使用。目前,采用同一种开发语言同时运行多个调试引擎可产生混乱的工作流(如当用户正查看具有两个调试器的 C 文件时,仅需要采用一个调试器植入断点)。此外,多核调试对话的数据显示方面还需要进行一定的工作。Eclipse 需要能够提供可针对特定调试环境进行逻辑分组的调试器视图。开发人员需要将每个内核的资源、表达式、寄存器及内存视图组合在一起,他们还必须能够轻松地区分不同内核的视图。此外,还需要在内核之间协调发布顺序,从而能够同时加载并启动复杂的系统。这些正是设备调试(Device Debugging)项目下一步将要改进的方面。
    如欲了解该项目的更多信息,请访问:www.eclipse.org/dsdp/dd。设备调试(Device Debugging)项目为开放源代码项目。诚邀各界厂商与开发人员广泛参与,共同定义使用情形、构建代码或构建基于高端技术的商用产品。
    33.JPG