使用 getinfo / getlocal / getupvalue 在 Lua 中获得所有变量以进行调试

我使用了这个函数从我的 Lua 应用程序中获得了几乎所有的变量,但是无法获取到局部变量...

例如在 main.lua 的根目录下: local test = 10

它无法被找到。

有什么想法吗?

注意:我正在一个 Love2D 应用程序中运行它,并且这个函数从一个 Love 回调函数 (love.draw) 中被调用。

function getvarvalue (name)
    local value, found

    -- 尝试获取局部变量
    local exit = false
    local level = 0
    while debug.getinfo(level) ~= nil do
        local i = 1
        while true do
            local n, v = debug.getlocal(level, i)
            if n then
                print("local "..i.." "..level.." name:"..n)
            end
            if not n then break end
            print(n)
            if n == name then
                value = v
                found = true
            end
            i = i + 1
        end
        if found then return value end
        level = level + 1
    end

    -- 尝试获取闭包变量
    level = 0
    while debug.getinfo(level) ~= nil do
        local func = debug.getinfo(level).func
        i = 1
        while true do
            local n, v = debug.getupvalue(func, i)
            if n~= nil then print("up "..i.." "..level.." "..n) end
            if not n then break end
            if n == name then return v end
            i = i + 1
        end
        if getfenv(func)[name] ~= nil then
            return getfenv(func)[name]
        end
        level = level + 1
    end

    -- 没有找到
    return "?"
end
点赞
用户7390956
用户7390956

正如@egor-skriptunoff所指出的,未在函数中使用的局部变量会“被杀掉”。它实际上是什么意思呢?

首先,Lua将函数视为值,这意味着love.draw实际上是一个字段,其赋值的值是一个函数。因此,函数本身是在运行时创建的。

考虑以下示例:

local myVar = 1

function love.draw()
    print(getvar("myVar"))
end

当Lua构造函数时,它会检查使用了哪些upvalues。这里发生了"kill off",因为它没有检测到myVar的使用,因此它不会创建对myVar的引用。即使它在love.update中更新。调试API则不会显示myVar,因为它只会显示被引用的值。

为了强制Lua保留一个引用,love.draw中的简单操作myVar = myVar就可以做到。

2022-09-24 11:31:24