Lua-调试


Lua提供了一个调试库,它为我们提供了创建自己的调试器的所有原始函数。尽管没有内置的 Lua 调试器,但我们有许多 Lua 调试器,由不同的开发人员创建,其中许多是开源的。

下表列出了 Lua 调试库中可用的函数及其用途。

先生。 方法与目的
1

调试()

进入调试交互模式,该模式保持活动状态,直到我们在一行中仅输入 cont 并按 Enter 键。用户可以在此模式下使用其他功能检查变量。

2

getfenv(对象)

返回对象的环境。

3

gethook(可选线程)

返回线程的当前钩子设置,作为三个值 - 当前钩子函数、当前钩子掩码和当前钩子计数。

4

getinfo(可选线程、函数或堆栈级别、可选标志)

返回包含有关函数的信息的表。你可以直接给出函数,也可以给出一个数字作为函数的值,这意味着该函数运行在给定线程的调用堆栈的函数级别 - 0 级是当前函数(getinfo 本身);level 1是调用getinfo的函数;等等。如果 function 是一个大于活动函数数量的数字,则 getinfo 返回 nil。

5

getlocal(可选线程、堆栈级别、本地索引)

返回具有堆栈级别的函数索引 local 的局部变量的名称和值。如果没有具有给定索引的局部变量,则返回 nil,并且在超出范围的级别调用时引发错误。

6

获取元表(值)

返回给定对象的元表,如果没有元表,则返回 nil。

7

获取注册表()

返回注册表,一个预定义的表,任何 C 代码都可以使用它来存储它需要存储的任何 Lua 值。

8

getupvalue(函数, 上值索引)

此函数返回函数 func 的索引 up 的名称和值。如果给定索引没有上值,则该函数返回 nil。

9

setfenv(函数或线程或用户数据,环境表)

将给定对象的环境设置为给定表。返回对象。

10

sethook(可选线程,钩子函数,带有“c”和/或“r”和/或“l”的钩子掩码字符串,可选指令数)

将给定函数设置为钩子。字符串掩码和计数描述了何时调用钩子。这里,每次 Lua 调用、返回和进入函数中的每一行代码时,都会分别调用 c、r 和 l。

11

setlocal(可选线程,堆栈级别,本地索引,值)

将值分配给具有堆栈级别函数的局部索引的局部变量。如果没有具有给定索引的局部变量,该函数将返回 nil,并且在级别超出范围的情况下调用时会引发错误。否则,它返回局部变量的名称。

12

setmetatable(值,元表)

将给定对象的元表设置为给定表(可以为零)。

13

setupvalue(函数,上值索引,值)

该函数将值赋给函数 func 的索引为 up 的值。如果给定索引没有上值,则该函数返回 nil。否则,它返回上值的名称。

14

回溯(可选线程、可选消息字符串、可选级别参数)

构建带有回溯的扩展错误消息。

上面的列表是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 - 调试器- 该项目是 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 - 具有远程调试、本地调试、语法突出显示、完成建议列表、参数命题引擎、高级断点管理(包括断点和命中计数的条件系统)、函数列表、全局和局部变量列表、监视、面向解决方案的管理。