每当Lua脚本发生错误时,除了通常的堆栈跟踪之外,我希望它将所有本地和全局变量的值写入屏幕/可选地写入文件。
我如何才能将此作为所有错误的默认行为?
答案 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);
}
}