改进Lua错误消息

每当 Lua 脚本出现错误时,我希望它将所有局部和全局变量的值写入屏幕/可选地写入文件——除了通常的堆栈跟踪。

我应该如何让所有错误都具有这种默认行为?

原文链接 https://stackoverflow.com/questions/3276305

点赞
stackoverflow用户107090
stackoverflow用户107090

如果你使用的是标准的 Lua 解释器,将 debug.traceback 替换为你自己的函数。如果你在程序中嵌入了 Lua,请在 lua_pcall 中使用你的回溯函数。

2010-07-19 00:55:37
stackoverflow用户282536
stackoverflow用户282536

更加正式的解决方案是在你的代码周围使用xpcall。

local function myerrhandler(errobj)
    print(debug.traceback())
    for k, v in pairs(_G) do
        print("GLOBAL:", k, v)
    end
    return false
end

xpcall(function()
    -- 在这里写你的代码
end, myerrhandler)
2010-07-21 14:20:46
stackoverflow用户220481
stackoverflow用户220481

你的错误处理程序可能会被覆盖。如果你正在从 C 调用 Lua,你可以钩入 luaG_errormsg 函数以始终打印堆栈信息。

在 Lua 中,编写:

local _HandlingError = 0
function _ErrorHandler ( errobj )
    if( _HandlingError == 0 ) then
        _HandlingError = 1
        local errStr = tostring(errobj) or ""
        if( type(errobj)=='table' ) then
          errStr = "Table: {" .. table.concat(errobj, ',') .. "}"
        end
        print("Error: \"" .. errStr .. "\"")
        --for k,v in pairs(_G) do print("GLOBAL:" , k,v) end
        if( type(errobj)=='thread' ) then
            print(debug.traceback(errobj))
        else
            print(debug.traceback('',2))
        end
        _HandlingError = 0
    end
    return false
end

然后在 ldebug.c 文件中,在 if(L->errfunc != 0) 后面加入以下内容:

else
{
    lua_getfield(L, LUA_GLOBALSINDEX, "_ErrorHandler");
    if (!lua_isfunction(L, -1)) {
        lua_pop(L, 1);
    }
    else {
        lua_pushvalue(L, 1);
        lua_call(L, 2, 1);
        lua_pop(L, 1);
    }
}
2012-07-24 19:21:12
stackoverflow用户1793220
stackoverflow用户1793220

StackTracePlus 模块可以在堆栈跟踪的每个级别上显示本地变量,满足您的需求。它不会转储整个全局表,但这可能会导致冗余。

要使用 LuaRocks 安装它,请执行以下操作:

luarocks install stacktraceplus

然后在您的代码中添加以下行:

local STP = require "StackTracePlus"
debug.traceback = STP.stacktrace

在 Lua 5.1 中,这将自动转换所有堆栈跟踪; 对于 Lua 5.2 代码,您需要像其他答案建议的那样使用 xpcall 包装您的代码。

2014-02-03 03:26:48