gdb调试lua_lua的调试器技术

来自转载:

简介:

LUA没有自带调试器,只提供了一套调试库,可以实现符合自己需要的调试器.晚上没事,改写了一下以前的一个GDB风格的LUA调试器,可嵌入到应用程序中,在需要的时候触发并调试,有需要的朋友可以参考下. 支持如下命令:

h             帮助信息

c             继续动行

s             单步运行(不跳过函数调用)

n             单步运行(跳过函数调用)

p var         打印变量值

b src:line    添加断点,注意src要写文件的绝对路径,例如 b script/main.lua:22

d num         删除断点

bl            列出所有断点

be num        启用一个断点

bd num        禁用一个断点

bt            打印调用栈

实现:

LUA支持用debug.sethook设置三种Hook:

一,每行代码执行时调用Hook函数

二,每个函数调用时执行Hook函数

三,每个函数返回时调用Hook函数

在Hook函数中,可以通过调用debug.getinfo得到当前LUA文件名,当前所执行代码的行号.所以,要实现针对行下断点,一个显尔易见的办法就是在每个HOOK中判断当前文件和当前行号是否是一个断点,是的话就中断下来(调用io.read()来等待输入).这样当然会比较慢,因为每行代码执行时都会去调用HOOK函数,但LUA一般是用来做逻辑而不是算术密集的操作,而且一般只是在开发期调试会使用hook,所以绝大部分情况下是足够用了.特殊情况下有效率要求时,可以使用下文介绍的另一种办法.

但在实际开发中碰到了个问题:如何实现n命令(单步运行,跳过函数调用),LUA的HOOK是每行代码都会触发,可以取得当前函数,所以单步运行时很容易知道是不是进入了一个新函数,但是如何在进入这个函数时不中断,在调用完成时才中断?最直观的想法是在n命令碰到函数时,自动在函数调用的下一行加入断点并运行.但是实际情况要复杂得多,比如函数调用下一行是空行,函数调用当前行有return,比如:

if ( foo() ) return end

这样就要写很多代码分析的代码来保证正确性,逻辑就写复杂了,放弃这种做法.

另一种想法是下函数执行hook和函数返回hook,执行hook触发时增量某个变量,返回hook扫许时减量某个变量,这样变量为0时就是返回到调用函数了(调用栈平衡),但是程序逻辑也变得复杂了,放弃这种做法.

最直观的办法是检查调用栈深度,因为被调用函数返回时,调用栈深度总是不会变的.但是LUA debug库没有检查调用栈深度的函数,还好LUA是开源的,动手加一个即可.最后的代码见下面,如有更简单的办法请告之:

在lua(5.1.4)源代码文件 ldblib.c中添加返回调用栈深度的函数:

static int db_traceback_count (lua_State *L) {

lua_Debug ar;

int index = 1;

while (lua_getstack(L, index, &ar))

index++;

lua_pushnumber( L, index - 1 );

return 1;

}

在static const luaL_Reg dblib[] 数组中添加一行函数注册:

{"traceback_count", db_traceback_count},

重新编译LUA.

为了像GDB一样在单步调试时能显示当前源代码,在C/C++层注册一个读取指定文件指定行的函数:

int get_file_line( lua_State *L )

{

const char *file = luaL_checkstring( L, 1 );

int line = lua_tonumber( L, 2 );

if ( line < 1 ) line = 1;

int n = 1;

char src[2046];

FILE *f = fopen( file, "r" );

if ( f )

{

while ( fgets( src, 2046, f ) )

{

if ( n == line )

{

int last = strlen(src) - 1;

if ( src[last] == '/n' )

s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值