2010-07-18 3 views
5

Всякий раз, когда в сценарии Lua возникает ошибка, я хотел бы, чтобы она записывала значения всех локальных и глобальных переменных на экран/необязательно в файл - в дополнение к обычной трассировке стека.Улучшение сообщений об ошибках Lua

Как я могу получить это поведение по умолчанию для всех ошибок?

ответ

3

Если вы используете стандартный интерпретатор Lua, замените debug.traceback на свою собственную функцию. Если вы встраиваете Lua в свою программу, используйте функцию отслеживания в lua_pcall.

+0

Спасибо, я буду экспериментировать с вашими рекомендациями. В связи с этим я вижу, что некоторые ссылки на списки рассылки на «pcall и сопрограммы не ладят». Я использую сопрограммы, следует ли использовать coxpcall и copcall? – proFromDover

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) 
0

Ваш обработчик ошибок может быть перезаписан. Если вы вызываете Lua из C, чтобы всегда печатать стек, вы можете подключиться к функции 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 после если (! 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); 
    } 
} 
2

Модуль StackTracePlus делает то, что вы хотите, отображая локальные переменные на каждом уровне трассировки стека. Он не сбрасывает всю таблицу глобальных таблиц, но это, вероятно, слишком велико.

Чтобы установить его с LuaRocks, используйте

luarocks install stacktraceplus 

Тогда в вашем коде, сделайте следующее:

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

В Lua 5.1 это будет автоматически конвертировать все следы стека; для кода Lua 5.2 вам необходимо обернуть свой код xpcall, как это предлагается в других ответах.

Смежные вопросы