嵌入式Lua脚本远程调试的设计.doc
文本预览下载声明
嵌入式Lua脚本远程调试的设计
摘 要:针对嵌入式Lua脚本特点,文章设计并定义了嵌入式Lua远程调试通信协议。协议提供了简单与宽松的通信过程。利用Lua语言提供的调试原语设计了调试代理,调试代理提供了一种简便的执行脚本的控制方法,具有一定的通用性,可以在多种操作系统之上实现。
关键词:远程调试Lua 脚本宿主程序调试代理
中图分类号:TM7 文献标识码:A 文章编号:1007-9416(2011)03-0102-03
1、引言
作为一种嵌入式语言,Lua可以嵌入到其他多种宿主语言之中,实现各个独立功能的胶合,从而形成完整功能,同时也可以实现应用功能的扩展,因此近年来得到了非常广泛的关注。
Lua是一种简洁、高效的和灵活的可扩展解释语言,通过Lua程序可以实现复杂的应用。但是软件的开发周期和成本与调试过程密切相关,调试时间在总开发时间中占据相当大的比例,因此调试器是软件开发必不可少的工具。
目前,在嵌入式系统软件开发中,调试通常采用如下几种方式:软件插桩、在线仿真与片上调试。但是在嵌入式环境中,运行于目标机宿主程序中的Lua程序代码与目标机平台无关,执行Lua代码的虚拟机(VM)模块本身可以视为一个特殊的处理器,同时由于上述调试方法与特定平台的交叉编译器密切相关,因此传统的调试器和调试方法不适用于对Lua程序的调试。虽然Lua内嵌了调试所必需的原语,但是并没有提供成型的调试器,因此设计Lua调试器对于嵌入式Lua产品的应用至关重要。
本文结合Lua语言调试原语,采用远程调试方法,设计了嵌入式环境下Lua远程调试涉及的关键内容。
2、远程调试
在嵌入式环境下,被调试目标程序运行的目标机环境与通用计算机的环境有很大的不同。通常嵌入式软件环境中目标机CPU处理能力有限、内存容量小、没有文件系统和操作系统等,调试器很难与目标程序一起运行在目标机器上,因此对嵌入式系统软件的调试一般不采用本地调试而采用远程调试的方式。远程调试涉及主机和目标机两个因素,需要在主机上通过调试器调试运行于目标机上的程序代码。在嵌入式环境中对于嵌入在宿主程序中的Lua程序的调试同样采用远程调试的方法。本文介绍的远程调试仅针对Lua程序,不涉及宿主程序的调试,因此无需关注对宿主程序的调试代码注入以及Lua脚本到宿主程序的调试穿越等方面问题。
在远程调试模式下,主机上运行的调试器通过特定协议在指定的端口发送各种调试命令到目标机的代理程序,通过协议接收用于查看和显示程序运行状态数据。目标机上调试代理程序分析并执行接收到的调试命令,通过语言本身具备的调试原语控制程序执行的并返回程序执行的各种当前状态和相关数据,图1。
实现完整的特定嵌入式环境下的Lua远程调试系统需要完成主机上的调试器软件、定义现目标机与主机之间的通信协议以及完成调试代理功能。在目标上涉及平台硬件以及操作系统部分的功能可以在宿主程序中实现,从而实现调试器与目标机的无关性,调试代理程序与平台及操作系统的无关性,使调试系统不依赖于特定的目标平台和特定的操作系统,为今后多平台调试系统的实现提供基础。
3、调试原语
Lua本身提供了一个编写调试系统所必需的具有的原语,即在目标机端实现了基本的与调式相关的自省函数(introspective function)和钩子函数(hook functon)。通过自省函数提供检查运行Lua程序各方面的数据,如:活动函数的栈,当前运行的行号等。
语言提供的由宿主程序使用的最主要的自省函数是lua_getinfo函数。其C语言函数原型为:
int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar);
它的第一个参数为当前执行的Lua状态或者线程指针;第二个参数为控制参数,决定自省函数返回当前指向的线程的哪些信息;第三个参数为活动记录指针,指针指向的内容为当前线程执行堆栈。通过自省函数可以获取当前执行的Lua函数定义位置、类型、名称、变量的类型、上值(upvalue)数量以及活动行的集合等丰富的执行状态信息。完整的活动记录内容描述如下:
struct lua_Debug {
int event; //事件类型
const char *name; //名称
const char *namewhat; //变量范围
const char *what; //函数类型
const char *source; //函数定义位置
int currentline; //准备执行行
int nups; //上值个数
int linedefined; //定义起
显示全部