- 6.10 – 调试库
- debug.debug ()
- debug.gethook ([thread])
- debug.getinfo ([thread,] f [, what])
- debug.getlocal ([thread,] f, local)
- debug.getmetatable (value)
- debug.getregistry ()
- debug.getupvalue (f, up)
- debug.getuservalue (u)
- debug.sethook ([thread,] hook, mask [, count])
- debug.setlocal ([thread,] level, local, value)
- debug.setmetatable (value, table)
- debug.setupvalue (f, up, value)
- debug.setuservalue (udata, value)
- debug.traceback ([thread,] [message [, level]])
- debug.upvalueid (f, n)
- debug.upvaluejoin (f1, n1, f2, n2)
6.10 – 调试库
这个库提供了 Lua 程序调试接口(§4.9)的功能。其中一些函数违反了 Lua 代码的基本假定(例如,不会从函数之外访问函数的局部变量;用户数据的元表不会被 Lua 代码修改;Lua 程序不会崩溃),因此它们有可能危害到其它代码的安全性。此外,库里的一些函数可能运行的很慢。
这个库里的所有函数都提供在表 debug
内。所有操作线程的函数,可选的第一个参数都是针对的线程。默认值永远是当前线程。
debug.debug ()
进入一个用户交互模式,运行用户输入的每个字符串。使用简单的命令以及其它调试设置,用户可以检阅全局变量和局部变量,改变变量的值,计算一些表达式,等等。输入一行仅包含 cont
的字符串将结束这个函数,这样调用者就可以继续向下运行。
注意,debug.debug
输入的命令在文法上并没有内嵌到任何函数中,因此不能直接去访问局部变量。
debug.gethook ([thread])
返回三个表示线程钩子设置的值:当前钩子函数,当前钩子掩码,当前钩子计数(debug.sethook
设置的那些)。
debug.getinfo ([thread,] f [, what])
返回关于一个函数信息的表。你可以直接提供该函数,也可以用一个数字 f
表示该函数。数字 f
表示运行在指定线程的调用栈对应层次上的函数:0 层表示当前函数(getinfo
自身);1 层表示调用 getinfo
的函数(除非是尾调用,这种情况不计入栈);等等。如果 f
是一个比活动函数数量还大的数字,getinfo
返回 nil。
只有字符串 what
中有描述要填充哪些项,返回的表可以包含 lua_getinfo
能返回的所有项。what
默认是返回提供的除合法行号表外的所有信息。对于选项 'f
' ,会在可能的情况下,增加func
域保存函数自身。对于选项 'L
' ,会在可能的情况下,增加activelines
域保存合法行号表。
例如,表达式 debug.getinfo(1,"n")
返回带有当前函数名字信息的表(如果找的到名字的话),表达式 debug.getinfo(print)
返回关于 print
函数的包含有所有能提供信息的表。
debug.getlocal ([thread,] f, local)
此函数返回在栈的 f
层处函数的索引为 local
的局部变量的名字和值。这个函数不仅用于访问显式定义的局部变量,也包括形参、临时变量等。
第一个形参或是定义的第一个局部变量的索引为 1 ,然后遵循在代码中定义次序,以次类推。其中只计算函数当前作用域的活动变量。负索引指可变参数;-1 指第一个可变参数。如果该索引处没有变量,函数返回 nil。若指定的层次越界,抛出错误。(你可以调用 debug.getinfo
来检查层次是否合法。)
以 '(
' (开括号)打头的变量名表示没有名字的变量(比如是循环控制用到的控制变量,或是去除了调试信息的代码块)。
参数 f
也可以是一个函数。这种情况下,getlocal
仅返回函数形参的名字。
debug.getmetatable (value)
返回给定 value
的元表。若其没有元表则返回 nil 。
debug.getregistry ()
返回注册表(参见 §4.5)。
debug.getupvalue (f, up)
此函数返回函数 f
的第 up
个上值的名字和值。如果该函数没有那个上值,返回 nil 。
以 '(
' (开括号)打头的变量名表示没有名字的变量(去除了调试信息的代码块)。
debug.getuservalue (u)
返回关联在 u
上的 Lua 值。如果 u
并非用户数据,返回 nil。
debug.sethook ([thread,] hook, mask [, count])
将一个函数作为钩子函数设入。字符串 mask
以及数字 count
决定了钩子将在何时调用。掩码是由下列字符组合成的字符串,每个字符有其含义:
- '
c
': 每当 Lua 调用一个函数时,调用钩子; - '
r
': 每当 Lua 从一个函数内返回时,调用钩子; - '
l
': 每当 Lua 进入新的一行时,调用钩子。 此外,传入一个不为零的count
,钩子将在每运行count
条指令时调用。
如果不传入参数,debug.sethook
关闭钩子。
当钩子被调用时,第一个参数是触发这次调用的事件:"call"
(或 "tail call"
),"return"
,"line"
, "count"
。对于行事件,钩子的第二个参数是新的行号。在钩子内,你可以调用 getinfo
,指定第 2 层,来获得正在运行的函数的详细信息(0 层指 getinfo
函数,1 层指钩子函数)。
debug.setlocal ([thread,] level, local, value)
这个函数将 value
赋给栈上第 level
层函数的第 local
个局部变量。如果没有那个变量,函数返回 nil 。如果 level
越界,抛出一个错误。(你可以调用 debug.getinfo
来检查层次是否合法。)否则,它返回局部变量的名字。
关于变量索引和名字,参见 debug.getlocal
。
debug.setmetatable (value, table)
将 value
的元表设为 table
(可以是 nil)。返回 value
。
debug.setupvalue (f, up, value)
这个函数将 value
设为函数 f
的第up
个上值。如果函数没有那个上值,返回 nil否则,返回该上值的名字。
debug.setuservalue (udata, value)
将 value
设为 udata
的关联值。udata
必须是一个完全用户数据。
返回 udata
。
debug.traceback ([thread,] [message [, level]])
如果 message
有,且不是字符串或 nil,函数不做任何处理直接返回 message
。否则,它返回调用栈的栈回溯信息。字符串可选项 message
被添加在栈回溯信息的开头。数字可选项 level
指明从栈的哪一层开始回溯(默认为 1 ,即调用 traceback
的那里)。
debug.upvalueid (f, n)
返回指定函数第 n
个上值的唯一标识符(一个轻量用户数据)。
这个唯一标识符可以让程序检查两个不同的闭包是否共享了上值。若 Lua 闭包之间共享的是同一个上值(即指向一个外部局部变量),会返回相同的标识符。
debug.upvaluejoin (f1, n1, f2, n2)
让 Lua 闭包 f1
的第 n1
个上值引用 Lua 闭包 f2
的第 n2
个上值。