关于Lua调试器开发基本思路是本文要介绍的内容,之前由于在游戏的服务端那要做个Lua远程调试器供任务部使用,现在做个简单的介绍.不妨把调试器的服务端的类叫CLuaDebug吧!
CLuaDebug初始化:
实现回调钩子函数
- ?static?void?LuaDebugCallBack(lua_State*?L,?lua_Debug*?ar) ?
- { ?
- ????lua_getinfo(?L,?"S",?ar); ?
- ????switch?(ar->event) ?
- ????{ ?
- ???????case?LUA_HOOKRET: ?
- ?????????m_iDeepFunc--; ?
- ?????????break; ?
- ???????case?LUA_HOOKCALL: ?
- ???????????m_iDeepFunc++; ?
- ????????break; ?
- ???????case?LUA_HOOKLINE: ?
- ??????????string?strSource?=?ar->source?+?1; ?
- ??????????ULONG?ulLine?=?ar->currentline; ?
- ??????????//打印变量(全局变量lua_pushvalue(state,?LUA_GLOBALSINDEX),堆栈信息(lua_getstack,?lua_getinfo(,?"nSlf",?&d))?,?局部变量(lua_getlocal)) ?
- ??????????....?... ?
- ????????break; ?
- ???????defalut: ?
- ?????????break; ?
- ????} ?
- }?
设置钩子函数:
小结:关于Lua调试器开发基本思路的内容介绍完了,希望通过本文的学习能对你有所帮助!
上文来自:http://mobile.51cto.com/iphone-286666.htm
?Lua - 调试接口
4 - 调试接口 The Debug Interface
Lua 没有内置的调试设施。它使用一种特殊的接口,这种接口依赖函数和?钩子(hooks)。该接口允许构造不同种类的调试器,分析器以及其他工具用以从解释器得到所需的信息。
4.1 - 堆栈及函数信息 Stack and Function Information
得到解释程序运行时堆栈信息的主要函数是:
int lua_getstack (lua_State *L,int level,lua_Debug *ar);
这个函数用一个指定等级的函数的?activation record?的标示符填充一个?lua_Debug
?结构,等级 0 是当前运行函数,然而等级?n+1?是在等级?n?上调用的函数。当没有错误发生时,lua_getstack
?返回 1;当在比栈更深的等级上调用的时候,它返回 0;
lua_Debug
?结构被用来携带一个处于活动状态的函数的各种信息:
typedef struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) `global',`local',`field',`method' */ const char *what; /* (S) `Lua' function,`C' function,Lua `main' */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) number of upvalues */ int linedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ ... } lua_Debug;
lua_getstack
?只填充结构的私有部分以备之后使用。要填充?lua_Debug
?其他有用信息,调用
int lua_getinfo (lua_State *L,const char *what,lua_Debug *ar);
这个函数发生错误是返回 0 (举个例子,一个无效的?what
?选项)。what
?字符串中的每个字符选择填充一些?ar
?结构的字段,把上面在?lua_Debug
?定义中用圆括号括起来的字母作为指示: `S
′ 填充在?source
,?linedefined
?和?what
?字段中;`l
′ 填充在?currentline
?字段中,等等...。而且,`f
′ 将正在运?性谒??燃渡系暮??谷攵颜弧?
想要从一个不处于活动状态的函数那得到信息(就是不在栈上的函数),你需要将其压入栈并且用?>
′ 作为?what
?字符串的开始。举个例子,要知道函数?f
?定义在第几行,你需要这样写
lua_Debug ar; lua_pushstring(L,"f"); lua_gettable(L,LUA_GLOBALSINDEX); /* get global `f' */ lua_getinfo(L,">S",&ar); printf("%d/n",ar.linedefined);
lua_Debug
?的字段有如下的含义:
-
source
?如果函数在一个字符串中定义,那么?source
?就是那个字符串。如果函数定义在一个文件中,source
开始于一个 `@
′ 后面跟随文件名。 -
short_src
?一个可打印版的?source
,用于错误信息。 -
linedefined
?函数定义起始的行号。 -
what
?如果这是一个Lua函数,显示?"Lua"
?字符串,?"C"
?为C 函数,"main"
?如果这是一个语句段的main部分,"tail"
?如果这是一个做了尾部调用的函数。在后面的情况里,Lua 没有其他关于这个函部的信息。 -
currentline
?代表当前函数执行到的行数。如果没有行信息可用,currentline
?被设置为?-1。 -
name
?一个所给函数合理的函数名。因为函数在Lua中属于第一类值,它们没有固定的名字:一些函数可能是多个全局变量的值,其他的可能只储存在一个表字段里。lua_getinfo
?函数检测函数如何被调用或者是否为一个全局变量的值以寻找一个合适的名字。如果找不到合适的名字,name
?被设置为?NULL
。 -
namewhat
?name
?字段的解释。根据函数如何被调用,namewhat
?的值可以是?"global"
,?"local"
,?"method"
,"field"
?或者?""
?(空字符串)。(当没有其他可选项的时候Lua使用空字符串代替) -
nups
?函数上值的数量。
4.2 - 操作局部变量和上值 Manipulating Local Variables and Upvalues
为了更多的操作局部变量和上值,调试接口使用索引:第一个参数或者局部变量索引为 1,以此类推,直到最后一个活动的局部变量。整个函数中的活动的上值没有特定的顺序。
下面的函数允许操作一个所给激活记录的局部变量:
const char *lua_getlocal (lua_State *L,const lua_Debug *ar,int n); const char *lua_setlocal (lua_State *L,int n);
参数?ar
?必须是一个被前一个?lua_getstack
?调用填充的有效的激活记录或者作为一个钩子函数的参数(见4.3)。lua_getlocal
?获得一个局部变量的索引?n
,将变量的值压入栈,并且返回变量名。lua_setlocal
?从栈顶分配一个值给变量并且返回变量名。当索引超过活动的局部变量的数量时,两个函数都返回?NULL
。
以下的函部可以操作所给函数的上值(不像局部变量,函数的上值即使在函数不处于活动状态的时候都可以被访问):
const char *lua_getupvalue (lua_State *L,int funcindex,int n); const char *lua_setupvalue (lua_State *L,int n);
这些函数可以作为Lua 函数使用也可以作为C 函数使用。(作为Lua 函数,上值是函数外部使用的局部变量,因此它被包含在函数闭包中。)funcindex
?指向栈中的一个函数。lua_getupvalue
?得到一个上值的索引?n
,将上值的值压入栈,并返回其变量名。lua_setupvalue
?从栈顶分配一个值给上值并返回变量名。当索引大于上值数量时,两个函数都返回?NULL
。对于C 函数来说,这些函数使用空字符串作为所有上值的变量名。
作为一个例子,下面的函数列举了所给等级的栈中的函数的所有局部变量名和上值变量名:
int listvars (lua_State *L,int level) { lua_Debug ar; int i; const char *name; if (lua_getstack(L,level,&ar) == 0) return 0; /* failure: no such level in the stack */ i = 1; while ((name = lua_getlocal(L,&ar,i++)) != NULL) { printf("local %d %s/n",i-1,name); lua_pop(L,1); /* remove variable value */ } lua_getinfo(L,"f",&ar); /* retrieves function */ i = 1; while ((name = lua_getupvalue(L,-1,i++)) != NULL) { printf("upvalue %d %s/n",1); /* remove upvalue value */ } return 1; }
4.3 - 钩子 Hooks
Lua offers a mechanism of hooks,which are user-defined C functions that are called during the program execution. A hook may be called in four different events: a?call?event,when Lua calls a function; a?return?event,when Lua returns from a function; a?line?event,when Lua starts executing a new line of code; and a?countevent,which happens every "count" instructions. Lua identifies these events with the following constants:LUA_HOOKCALL
,?LUA_HOOKRET
?(or?LUA_HOOKTAILRET
,see below),?LUA_HOOKLINE
,and?LUA_HOOKCOUNT
.
A hook has type?lua_Hook
,defined as follows:
typedef void (*lua_Hook) (lua_State *L,lua_Debug *ar);
You can set the hook with the following function:
int lua_sethook (lua_State *L,lua_Hook func,int mask,int count);
func
?is the hook.?mask
?specifies on which events the hook will be called: It is formed by a disjunction of the constants?LUA_MASKCALL
,?LUA_MASKRET
,?LUA_MASKLINE
,and?LUA_MASKCOUNT
. The?count
?argument is only meaningful when the mask includes?LUA_MASKCOUNT
. For each event,the hook is called as explained below:
- The call hook?is called when the interpreter calls a function. The hook is called just after Lua enters the new function.
- The return hook?is called when the interpreter returns from a function. The hook is called just before Lua leaves the function.
- The line hook?is called when the interpreter is about to start the execution of a new line of code,or when it jumps back in the code (even to the same line). (This event only happens while Lua is executing a Lua function.)
-
The count hook?is called after the interpreter executes every?
count
?instructions. (This event only happens while Lua is executing a Lua function.)
A hook is disabled by setting?mask
?to zero.
You can get the current hook,the current mask,and the current count with the following functions:
lua_Hook lua_gethook (lua_State *L); int lua_gethookmask (lua_State *L); int lua_gethookcount (lua_State *L);
Whenever a hook is called,its?ar
?argument has its field?event
?set to the specific event that triggered the hook. Moreover,for line events,the field?currentline
?is also set. To get the value of any other field in?ar
,the hook must call?lua_getinfo
. For return events,?event
?may be?LUA_HOOKRET
,the normal value,or?LUA_HOOKTAILRET
. In the latter case,Lua is simulating a return from a function that did a tail call; in this case,it is useless to calllua_getinfo
.
While Lua is running a hook,it disables other calls to hooks. Therefore,if a hook calls back Lua to execute a function or a chunk,that execution occurs without any calls to hooks.
上文来自:http://blog.csdn.net/skyremember/article/details/3139727