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的函数;等等。如果 function 是一个大于活动函数数量的数字,则 getinfo 返回 nil。5 getlocal(optional thread, stack level, local index)返回堆栈级别具有函数索引 local 的局部变量的名称和值。如果没有具有给定索引的局部变量,则返回 nil,并在调用超出范围的级别时引发错误。6 getmetatable(value)返回给定对象的元表,如果没有元表,则返回 nil。7 getregistry()返回注册表,这是一个预定义的表,任何 C 代码都可以使用它来存储它需要存储的任何 Lua 值。8 getupvalue(function, upvalue index)此函数返回带有函数 func 索引 up 的 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)将给定对象的元表设置为给定表(可以为零)。13 setupvalue(function, upvalue index, value)此函数将值分配给函数 func 索引为 up 的 upvalue。如果给定索引没有上值,则该函数返回 nil。否则,它返回上值的名称。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
在此示例中,计数器每次被调用时都会更新 1。我们可以使用 getupvalue 函数查看局部变量的当前状态。然后我们将局部变量设置为一个新值。这里,在调用 set 操作之前 n 是 2。使用 setupvalue 函数将其更新为 10。现在当我们调用 counter 函数时,它将返回 11 而不是 3。 -
调试类型
- 命令行调试
- 图形调试
命令行调试
命令行调试是使用命令行在命令和打印语句的帮助下进行调试的调试类型。有许多可用于 Lua 的命令行调试器,下面列出了其中的一些。-
RemDebug− RemDebug 是 Lua 5.0 和 5.1 的远程调试器。它可以让你远程控制另一个 Lua 程序的执行,设置断点并检查程序的当前状态。RemDebug 还可以调试 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 中的断点、单步执行、单步执行和其他按钮,可以进行可视化表示和逐步控制执行。Lua 有许多图形调试器,它包括以下内容。-
SciTE − Lua 的默认 Windows IDE 提供了多种调试工具,如断点、单步执行、单步执行、单步执行、观察变量等。
-
Decoda − 这是具有远程调试支持的图形调试器。
-
ZeroBrane Studio− Lua IDE 集成远程调试器、堆栈视图、观察视图、远程控制台、静态分析器等。与 LuaJIT、Love2d、Moai 和其他 Lua 引擎配合使用;Windows、OSX 和 Linux。开源。
-
akdebugger - Eclipse 的调试器和编辑器 Lua 插件。
-
luaedit − 具有远程调试、本地调试、语法高亮、完成建议列表、参数命题引擎、高级断点管理(包括断点条件系统和命中计数)、函数列表、全局和局部变量列表、监视、面向解决方案的管理。