改进Lua错误消息

时间:2010-07-18 16:29:22

标签: debugging lua

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

我如何才能将此作为所有错误的默认行为?

4 个答案:

答案 0 :(得分:3)

如果您使用的是标准的Lua解释器,请将debug.traceback替换为您自己的功能。如果您在程序中嵌入Lua,请使用lua_pcall中的追溯功能。

答案 1 :(得分:2)

StackTracePlus模块执行您想要的操作,在堆栈跟踪的每个级别显示本地变量。它不会转储整个全局表,但这可能有点过分。

要使用LuaRocks安装它,请使用

luarocks install stacktraceplus

然后在你的代码中,执行:

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

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

答案 2 :(得分:1)

更合适的解决方案是在整个代码周围使用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 ()
--Your code here
end , myerrhandler )

答案 3 :(得分:0)

您的错误处理程序可能会被覆盖。如果您从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 中,在之后添加 luaG_errormsg 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);
    }
}