Lua进阶教程(一) 调试
Lua提供了一个调试库,该库为创建自定义调试器提供了原始函数。虽然Lua缺乏内置调试器,但有许多Lua调试器可用,其中许多是开源的。
Lua调试库中可用的功能如下表:
序号 | 方法 & 目的 |
---|---|
1 | debug():进入交互式调试模式,保持活动状态,直到在一行中仅输入"cont"并按回车键。用户可以使用其他函数在此模式下检查变量。 |
2 | getfenv(object):返回对象的环境。 |
3 | gethook(optional thread):返回线程的当前钩子设置-三个值, 当前钩子函数、当前钩子掩码和当前钩子计数。 |
4 | getinfo(optional thread, function or stack level, optional flag):返回有关函数的信息表。可以直接提供函数,也可以将一个数字作为函数的值,该数字表示给定线程堆栈调用级别 - 级别0是当前函数(getinfo本身);级别1是调用getinfo的函数;依此类推。如果级别大于活动函数的调用层次,则getinfo返回nil。 |
5 | getlocal(optional thread, stack level, local index):返回给定堆栈级别上函数的局部变量的名称和值。如果在此级别没有局部变量,则返回nil,并在调用范围超出范围时引发错误。 |
6 | getmetatable(value):返回给定对象的元表,如果没有元表,则返回nil。 |
7 | getregistry():返回注册表,这是一个预定义的表,任何C代码都可用它来存储需要存储的任何Lua值。 |
8 | getupvalue(function, upvalue index):返回指定索引的函数的upvalue的名称和值。如果没有具有给定索引的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):将给定函数设置为钩子。字符串掩码和数字计数描述了何时调用钩子。在此处,c 、r 和l 分别在Lua调用、返回和进入函数的每一行时被调用。 |
11 | setlocal(optional thread, stack level, local index, value):为堆栈级别上函数的本地变量的索引local分配值。如果没有具有给定索引的本地变量,则函数返回nil,并在调用范围超出范围时引发错误。否则,它将返回本地变量的名称。 |
12 | setmetatable(value, metatable):将给定对象的元表设置为给定表(可以为nil)。 |
13 | setupvalue(function, upvalue index, value):为给定索引的函数设置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
until not name
print(counter())
执行时,上述程序输出:
1
2
index 1 k = 1
index 2 n = 2
11
在本例中,计数器每次调用时都会增加一个。我们使用“getupvalue”函数来查看局部变量,然后使用“setupvalue”修改它们。在这里,n
最初是2,但使用setupvalue
更新为10,计数器在调用时返回11而不是3。
调试类型
- 命令行调试
- 图形调试Command
命令行调试
命令行调试在命令行界面输入调试指令和打印语句来调试代码。Lua有几个命令行调试器可用:
-
RemDebug:Lua 5.0和5.1的远程调试器,允许远程控制另一个Lua程序的执行,设置断点,并检查程序的当前状态。它还可以调试CGILua脚本。
-
clidebugger:用纯Lua编写的Lua 5.1的简单命令行界面调试器。它不依赖于标准的Lua 5.1库以外的任何东西。它受到RemDebug的启发,但没有远程调试功能。
-
ctrace:用于跟踪Lua API调用的工具。
-
xdbLua:适用于Windows平台的简单Lua命令行调试器。
-
LuaInterface - Debugger:该项目是LuaInterface的扩展,它将内置的Lua调试界面提升到更高的水平。与调试器的交互由事件和方法调用完成 。
-
Rldb:这是一个通过套接字的远程Lua调试器,在Windows和Linux上都可用。它提供了比现有任何其他调试器更多的功能。
-
ModDebug:允许远程控制另一个Lua程序的执行,设置断点,并检查程序的当前状态。
图形调试
图形调试涉及使用集成开发环境(IDE),IDE提供可视化调试功能,如变量值、堆栈跟踪和其他相关信息。 通过可视化方式展现,单步控制语句执行。具体功能包括断点,step into,step over 和其他一些功能按钮。
Lua有几个图形调试器可用:
-
SciTE:Lua的默认Windows IDE,提供多种调试设施,如断点、分步执行控制和变量观察。
-
Decoda:支持远程调试的图形调试器。
-
ZeroBrane Studio:集成远程调试器、堆栈视图、观察视图、远程控制台、静态分析器等的Lua IDE。 它适用于LuaJIT、Love2d、Moai和其他Lua引擎,支持Windows、OSX和Linux。 它是开源的。
-
akdebugger:Eclipse的Lua插件,具有调试和编辑功能。
-
luaedit:具有远程调试、本地调试、语法高亮显示、完成提案列表、高级断点管理(包括断点和命中计数的条件系统)、函数列表、全局和局部变量列表、监视、面向解决方案的管理。