10391

52 分钟

#Lua 的 Debug 模块

Debug 模块为 Lua 程序提供了调试接口。使用此模块时应格外小心,其中的一些函数违反了 Lua 代码的基本假设(例如,函数内部的变量不能从外部访问;用户数据元表不能被 Lua 代码修改;Lua 程序不会崩溃),因此可能会危及原本安全的代码。并且某些函数可能运行缓慢。

函数说明
debug.debug启动调试模式
debug.getinfo获取函数信息
debug.gethook获取调试钩子
debug.sethook设置调试钩子
debug.getlocal获取栈上局部变量
debug.setlocal设置栈上局部变量
debug.getmetatable获取元表
debug.setmetatable设置元表
debug.getregistry获取注册表
debug.getupvalue获取闭包上值表
debug.setupvalue设置闭包上值表
debug.upvalueid获取闭包上值 ID
debug.upvaluejoin使闭包引用另一个闭包的上值
debug.getuservalue获取用户值
debug.setuservalue设置用户值
debug.traceback获取栈的回溯信息

#debug.debug

debug.debug ()

说明

进入调试模式的交互式命令行,将用户输入的字符串作为 Lua 代码运行,输入 cont 即可退出调试模式继续运行程序。

参数

返回值

示例

local n = 10 -- 不能访问局部变量 text = "https://xplanc.org/" -- 可以访问全局变量 debug.debug ()

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.gethook

debug.gethook ([thread])

说明

获取线程 thread 的调试钩子函数。

参数

  • thread - 线程;默认为当前线程

返回值

  • 返回调试钩子函数

#debug.getinfo

debug.getinfo ([thread,] f [, what])

说明

获取函数信息的表。

参数

  • thread - 线程;默认为当前线程
  • f - 函数或函数在栈上的层级
  • what - 指定想要的信息;默认为 "nSluf"
what 接受的值含义
n函数名及调用方式(name, namewhat
S源代码信息(short_src, linedefined, lastlinedefined, what, source
l当前行号(currentline
u函数的上值与参数信息(nups, nparams, isvararg
f返回实际的函数本身(func
L包含该函数中哪些行有可执行代码(activelines 表)

返回值

  • 返回函数信息表

示例

function level1() print(debug.getinfo(0)['name']) -- 按栈上位置获取信息 print(debug.getinfo(1)['name']) print(debug.getinfo(2)['name']) print(debug.getinfo(3)['name']) end function level2() level1() end function level3() level2() end function main() level3() end main() local info = debug.getinfo(main, 'nl') -- 获取指定函数信息 for k,v in pairs(info) do print(k, v) end

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.getlocal

debug.getlocal ([thread,] f, local)

说明

获取栈上 f 层级中第 local 个局部变量。

参数

  • thread - 线程;默认为当前线程
  • f - 栈上层级
  • local - 局部变量的序号

返回值

  • 成功时返回局部变量的名称和值
  • 失败时返回 nil

示例

function demo() local x = 10 local y = 20 local z = 30 print(debug.getlocal(1, 1)) print(debug.getlocal(1, 2)) print(debug.getlocal(1, 3)) end demo()

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.getmetatable

debug.getmetatable (value)

说明

获取 value 的元表。

参数

  • value - 要获取元表的对象

返回值

  • 返回对象的元表

示例

local metatable = debug.getmetatable("") -- 获取字符串的元表 for k,v in pairs(metatable) do print(k, v) end

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.getregistry

debug.getregistry ()

说明

获取注册表。

Lua 的注册表是一个由 C API 维护的全局表,用于在 C 和 Lua 之间安全地交换和保存数据,始终可以通过伪索引 LUA_REGISTRYINDEX 进行访问。

参数

返回值

  • 返回 Lua 的注册表

示例

for k,v in pairs(debug.getregistry()) do print(k, v) end

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.getupvalue

debug.getupvalue (f, up)

说明

获取闭包 f 的第 up 个上值。

参数

  • f - 闭包
  • up - 上值的序号

返回值

  • 成功时返回上值的的名称和值
  • 失败时返回 nil

示例

function demo() local x = 10 -- 外层局部变量,即上值 local y = 20 local z = 30 -- 返回闭包 return function() print(x, z) -- 只有被引用的外层变量才会被捕获为上值 end end -- 创建闭包 local closure = demo() print(debug.getupvalue(closure, 1)) -- _ENV,调用函数时会创建这个局部变量 print(debug.getupvalue(closure, 2)) -- x print(debug.getupvalue(closure, 3)) -- z

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.getuservalue

debug.getuservalue (u, n)

说明

获取与用户数据 u 关联的第 n 个用户值。

参数

  • u - 用户数据
  • n - 用户值的序号

返回值

  • 成功时返回用户的的名称和值
  • 失败时返回 nil

#debug.sethook

debug.sethook ([thread,] hook, mask [, count])

说明

设置调试钩子函数,钩子函数在特定事件发生时被调用。

只有最后一个钩子是有效的,无法为不同的事件同时设置钩子。

参数

  • thread - 线程;默认为当前线程
  • hook - 钩子函数
  • mask - 事件掩码组合字符串
    • 'c' - 每次 Lua 调用函数时都会调用该钩子函数,参数为事件
    • 'r' - 每次 Lua 从函数返回时都会调用该钩子函数,参数为事件
    • 'l' - 每次 Lua 进入新行时该钩子函数,参数为事件和行号
  • count - 除事件外,每执行 count 条指令触发一次钩子函数;默认为 0 不触发

返回值

示例

local function hook(event, line) print(event, line) end debug.sethook(hook, "l") -- 每行触发 -- 空行不会触发钩子 print("NOP") print("NOP") print("NOP")

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.setlocal

debug.setlocal ([thread,] level, local, value)

说明

将栈上 level 层级处的第 local 个局部变量的值设为 value

参数

  • thread - 线程;默认为当前线程
  • f - 栈上层级
  • local - 局部变量的序号
  • value - 要设为的值

返回值

  • 成功时返回被修改的变量名
  • 失败时返回 nil

示例

function inner() debug.setlocal(2, 1, "Hello") debug.setlocal(2, 2, "Primers") debug.setlocal(2, 3, "编程伙伴") end function outer() local x = 10 local y = 20 local z = 30 inner() print(x, y, z) end outer()

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.setmetatable

debug.setmetatable (value, table)

说明

将对象 value 的元表设为 metatable;如果 value 已有的元表包含 __metatable 字段则会引发错误。

参数

  • value - 要设置元表的对象,可以时表或用户数据
  • metatable - 要设置的元表,如果是 nil 则移除对象的元表

返回值

  • 返回 value

示例

local t1 = {value = 10} local t2 = {value = 20} -- 元表,重载运算符 local metatable = { __add = function(x, y) return {value = x.value + y.value} end, __sub = function(x, y) return {value = x.value - y.value} end, __mul = function(x, y) return {value = x.value * y.value} end, __div = function(x, y) return {value = x.value / y.value} end, } -- 设置元表 debug.setmetatable(t1, metatable) debug.setmetatable(t2, metatable) -- 使用 print((t1 + t2).value) print((t1 - t2).value) print((t1 * t2).value) print((t1 / t2).value)

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.setupvalue

debug.setupvalue (f, up, value)

说明

将闭包 f 的第 up 个上值设为 value

参数

  • f - 闭包
  • up - 上值的序号
  • value - 要设为的值

返回值

  • 被修改的上值变量名

示例

-- 外层局部变量,即上值 local x = 10 local y = 20 local z = 30 -- 创建闭包 local closure = function() print(x, y, z) -- 只有被引用的外层变量才会被捕获为上值 end -- 修改上值 debug.setupvalue(closure, 2, 'Hello') debug.setupvalue(closure, 3, 'Primers') debug.setupvalue(closure, 4, '编程伙伴') -- 调用闭包 closure() -- 外层变量也被改变 print(x, y, z)

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.setuservalue

debug.setuservalue (u, value, n)

说明

将与用户数据 u 关联的第 n 个用户值设置 value

参数

  • u - 用户数据
  • value - 要设为的值
  • n - 用户数据的序号

返回值

  • 返回 u

#debug.traceback

debug.traceback ([thread,] [message [, level]])

说明

生成调用栈回溯信息。

参数

  • thread - 线程;默认为当前线程
  • message - 附加信息;如果这个参数不是字符串或 nil 则直接返回这个参数
  • level - 从调用栈的第几层开始记录

返回值

  • 返回生成的信息

示例

function level1() print(debug.traceback("附加信息 https://xplanc.org/")) end function level2() level1() end function level3() level2() end function main() level3() end main()

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.upvalueid

debug.upvalueid (f, n)

说明

获取闭包 f 的第 up 个上值的唯一 ID(类型为轻量用户数据)。

通过返回的 ID 可以检测不同的闭包是否引用同一个上值。

参数

  • f - 闭包
  • up - 上值的序号

返回值

  • 返回上值的唯一 ID(轻量用户数据)

示例

local function outer() local a = 10 local b = 20 local function f1() return a end local function f2() return a end local function f3() return b end return f1, f2, f3 end local f1, f2, f3 = outer() local id1 = debug.upvalueid(f1, 1) local id2 = debug.upvalueid(f2, 1) local id3 = debug.upvalueid(f3, 1) print(id1 == id2) --> true (f1 和 f2 的上值 a 是同一个) print(id1 == id3) --> false (f1 的 a 和 f3 的 b 不同)

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#debug.upvaluejoin

debug.upvaluejoin (f1, n1, f2, n2)

说明

让闭包 f1 的第 n1 个上值引用闭包 f2 的第 n2 个上值。

参数

  • f1 - 目标闭包
  • n1 - 目标上值序号
  • f2 - 源闭包
  • n2 - 源上值序号

返回值

示例

local function outer() local a = 10 local b = 20 local function f1() return a end -- 引用 a local function f2() return b end -- 引用 b return f1, f2 end local f1, f2 = outer() -- 打印原始值 print(f1(), f2()) --> 10 20 -- 让 f2 的上值指向 f1 的上值 debug.upvaluejoin(f2, 1, f1, 1) print(f1(), f2()) --> 10 10

>>> Establishing WebAssembly Runtime.

>>> Standby.

Powered by Shift.

#推荐阅读

The Debug Library - Lua 5.4 Reference Manual

创建于 2025/10/30

更新于 2025/10/30