Lua - 调试

Lua提供了一个调试库,它为我们提供了创建自己的调试器的所有原始函数.即使没有内置的Lua调试器,我们也有许多Lua调试器,由各种开发人员创建,其中许多是开源的.

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

Sr.No.方法&目的
1

debug()

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

2

getfenv(object)

返回对象的环境.

3

gethook(optional thread)

返回线程的当前挂钩设置,为三个值 : 当前钩子函数,当前钩子掩码和当前钩子计数.

4

getinfo(optional thread, function or stack level, optional flag)

返回表有关功能的信息.你可以直接给出函数,或者你可以给一个数字作为函数的值,这意味着函数在给定线程的调用堆栈的level函数中运行 :  level 0是当前函数(getinfo本身); level 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(函数,upvalue index)

此函数返回函数func的索引向上的名称和upvalue的值.如果没有给定索引的upvalue,函数返回nil.

9

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

设置给定对象的环境到给定的表.返回对象.

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)

将给定对象的元表设置为给定表(可以是nil).

13

setupvalue(function, upvalue index, value)

此函数将值赋值给upvalue,函数func的索引为up.如果给定索引没有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

In在这个例子中,计数器每次调用时都会更新一次.我们可以使用getupvalue函数查看局部变量的当前状态.然后,我们将局部变量设置为新值.这里,在调用set操作之前n为2.使用setupvalue函数,它更新为10.现在当我们调用计数器函数时,它将返回11而不是3.

调试类型

  • 命令行调试

  • 图形化调试

命令行调试

命令行调试是在命令和打印语句的帮助下使用命令行进行调试的调试类型. Lua有许多命令行调试器,下面列出了一些.

  • RemDebug :  RemDebug是Lua 5.0和5.1的远程调试器.它允许您远程控制另一个Lua程序的执行,设置断点并检查程序的当前状态. RemDebug还可以调试CGILua脚本.

  • clidebugger : 一个简单的命令行界面调试器,用于Lua 5.1,用纯Lua编写.除了标准的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 : 这包括远程调试,本地调试,语法突出显示,完成建议列表,参数命题引擎,高级断点管理(包括断点和命中计数的条件系统),功能列表,全局和局部变量列表,监视,面向解决方案的管理.