Lua提供了一个调试库,它提供了创建自己的调试器的原始函数。 即使没有内置的Lua调试器,也有许多第三方Lua调试器,由各种开发人员创建,其中许多是开源的。
下表中列出了Lua调试库中可用的功能及其用法。
编号 | 方法 | 描述 |
---|---|---|
1 | debug() |
进入用于调试的交互模式,该模式保持活动状态,直到用户只输入一行中的cont 并按Enter键。 用户可以使用其他功能在此模式下检查变量。 |
2 | getfenv(object) |
返回对象的环境。 |
3 | gethook(optional thread) |
返回线程的当前挂钩设置,有三个值 - 当前挂钩函数,当前挂钩掩码和当前挂钩计数。 |
4 | getinfo(optional thread, function or stack level, optional flag) |
返回一个包含函数信息的表。可以直接给出函数,或者可以给一个数字作为函数的值,在给定线程的调用堆栈的级别函数上运行的函数 - 级别0 为当前函数(getinfo 本身); 级别1 为调用getinfo 的函数;等等。 如果function 是一个大于活动函数数的数字,则getinfo 返回nil 。 |
5 | getlocal(optional thread, stack level, local index) |
|
6 | getmetatable(value) |
返回给定对象的元表,如果没有元表,则返回nil 。 |
7 | getregistry() |
返回注册表表,这是一个预定义的表,任何C语言代码都可以使用它来存储它需要存储的任何Lua值。 |
8 | getupvalue(function, upvalue index) |
此函数返回upvalue 的名称和值,索引为函数func 。 如果给定索引没有upvalue ,则函数返回nil 。 |
9 | setfenv(function or thread or userdata, environment table) |
将给定对象的环境设置为给定表,返回对象。 |
10 | sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count) |
将给定函数设置为钩子。 字符串掩码和数字计数描述了何时调用挂钩。 这里,每次Lua调用,返回并分别输入函数中的每一行代码时,都会调用c ,r 和l 。 |
11 | setlocal(optional thread, stack level, local index, value) |
使用堆栈级别的函数的索引local 将值赋给局部变量。 如果没有具有给定索引的局部变量,则该函数返回nil ,并且当使用超出范围的级别调用时引发错误。 否则,它返回局部变量的名称。 |
12 | setmetatable(value, metatable) |
将给定对象的metatable 设置为给定表(可以为nil )。 |
13 | setupvalue(function, upvalue index, value) |
此函数使用函数func 的索引up 将值赋给upvalue 。 如果给定索引没有upvalue ,则函数返回nil 。 否则,它返回upvalue 的名称。 |
14 | traceback(optional thread, optional message string, optional level argument) |
使用回溯构建扩展错误消息。 |
上面的列表是Lua中完整的调试函数列表,经常使用一个上述函数的库,并提供更简单的调试。 使用这些函数并创建我们自己的调试器非常复杂,并不是优选的。 下面来看一个简单使用调试功能的例子。
function myfunction () print(debug.traceback("Stack trace")) print(debug.getinfo(1)) print("Stack trace end") return 10 end myfunction () print(debug.getinfo(1))
当运行上面的程序时,将获得如下所示的堆栈跟踪 -
Stack trace stack traceback: test2.lua:2: in function 'myfunction' test2.lua:8: in main chunk [C]: ? table: 0054C6C8 Stack trace end
在上面的示例程序中,使用调试库中提供的debug.trace
函数打印堆栈跟踪。 debug.getinfo
获取函数的当前表。
开发人员经常为了知道函数的局部变量以进行调试。 为此,可以使用getupvalue
和使用setupvalue
并设置这些局部变量。 一个简单的例子如下所示 -
function newCounter () local n = 0 local k = 0 return function () k = n n = n + 1 return n end end counter = newCounter () print(counter()) print(counter()) local i = 1 repeat name, val = debug.getupvalue(counter, i) if name then print ("index", i, name, "=", val) if(name == "n") then debug.setupvalue (counter,2,10) end i = i + 1 end -- if until not name print(counter())
当运行上面的程序时,将获得如下所示的堆栈跟踪 -
1 2 index 1 k = 1 index 2 n = 2 11
在此示例中,计数器每次调用时都会更新一次。 可以使用getupvalue
函数查看局部变量的当前状态。 然后,将局部变量设置为新值。 这里,在调用set
操作之前n
为2
。 使用setupvalue
函数,它更新为10
。现在当调用计数器函数时,它将返回11
而不是3
。
在Lua中,调试类型主要有两种 -
1. 命令行调试
命令行调试是使用命令和打印语句在命令行进行调试的调试类型。 Lua有许多命令行调试器,下面列出了一些。
RemDebug - RemDebug是Lua 5.0
和Lua 5.1
的远程调试器。 它允许远程控制另一个Lua程序的执行,设置断点并检查程序的当前状态。 RemDebug 还可以调试CGILua脚本。
clidebugger - 它是Lua 5.1的简单命令行界面调试器,用纯Lua编写。 除了标准的Lua 5.1库之外,它不依赖于任何其他东西。 它的灵感来自RemDebug,但没有远程工具。
2. 图形调试
在IDE下可以进行图形调试,在IDE中可为各种状态(如变量值,堆栈跟踪和其他相关信息)进行可视化调试。 借助断点,步入,步进和IDE中的其他按钮,可以实现可视化表示和逐步控制执行。
Lua有许多图形调试器,它包括以下内容-