extract debugging code to internal/debugging module
This commit is contained in:
parent
0e2b203fb2
commit
284f24433c
146
res/modules/internal/debugging.lua
Normal file
146
res/modules/internal/debugging.lua
Normal file
@ -0,0 +1,146 @@
|
||||
local breakpoints = {}
|
||||
local dbg_steps_mode = false
|
||||
local dbg_step_into_func = false
|
||||
local hook_lock = false
|
||||
local current_func
|
||||
local current_func_stack_size
|
||||
|
||||
local __parse_path = parse_path
|
||||
local _debug_getinfo = debug.getinfo
|
||||
local _debug_getlocal = debug.getlocal
|
||||
local __pause = debug.pause
|
||||
local __error = error
|
||||
local __sethook = debug.sethook
|
||||
|
||||
-- 'return' hook not called for some functions
|
||||
-- todo: speedup
|
||||
local function calc_stack_size()
|
||||
local s = debug.traceback("", 2)
|
||||
local count = 0
|
||||
for i in s:gmatch("\n") do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local is_debugging = debug.is_debugging()
|
||||
if is_debugging then
|
||||
__sethook(function (e, line)
|
||||
if e == "return" then
|
||||
local info = _debug_getinfo(2)
|
||||
if info.func == current_func then
|
||||
current_func = nil
|
||||
end
|
||||
end
|
||||
if dbg_steps_mode and not hook_lock then
|
||||
hook_lock = true
|
||||
|
||||
if not dbg_step_into_func then
|
||||
local func = _debug_getinfo(2).func
|
||||
if func ~= current_func then
|
||||
return
|
||||
end
|
||||
if current_func_stack_size ~= calc_stack_size() then
|
||||
return
|
||||
end
|
||||
end
|
||||
current_func = func
|
||||
__pause("step")
|
||||
debug.pull_events()
|
||||
end
|
||||
hook_lock = false
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
return
|
||||
end
|
||||
local source = _debug_getinfo(2).source
|
||||
if not bps[source] then
|
||||
return
|
||||
end
|
||||
current_func = _debug_getinfo(2).func
|
||||
current_func_stack_size = calc_stack_size()
|
||||
__pause("breakpoint")
|
||||
debug.pull_events()
|
||||
end, "lr")
|
||||
end
|
||||
|
||||
local DBG_EVENT_SET_BREAKPOINT = 1
|
||||
local DBG_EVENT_RM_BREAKPOINT = 2
|
||||
local DBG_EVENT_STEP = 3
|
||||
local DBG_EVENT_STEP_INTO_FUNCTION = 4
|
||||
local DBG_EVENT_RESUME = 5
|
||||
local DBG_EVENT_GET_VALUE = 6
|
||||
local __pull_events = debug.__pull_events
|
||||
local __sendvalue = debug.__sendvalue
|
||||
debug.__pull_events = nil
|
||||
debug.__sendvalue = nil
|
||||
|
||||
function debug.get_pack_by_frame(func)
|
||||
local prefix, _ = __parse_path(_debug_getinfo(func, "S").source)
|
||||
return prefix
|
||||
end
|
||||
|
||||
function debug.pull_events()
|
||||
if not is_debugging then
|
||||
return
|
||||
end
|
||||
if not debug.is_debugging() then
|
||||
is_debugging = false
|
||||
__sethook()
|
||||
end
|
||||
local events = __pull_events()
|
||||
if not events then
|
||||
return
|
||||
end
|
||||
for i, event in ipairs(events) do
|
||||
if event[1] == DBG_EVENT_SET_BREAKPOINT then
|
||||
debug.set_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_RM_BREAKPOINT then
|
||||
debug.remove_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_STEP then
|
||||
dbg_steps_mode = true
|
||||
dbg_step_into_func = false
|
||||
elseif event[1] == DBG_EVENT_STEP_INTO_FUNCTION then
|
||||
dbg_steps_mode = true
|
||||
dbg_step_into_func = true
|
||||
elseif event[1] == DBG_EVENT_RESUME then
|
||||
dbg_steps_mode = false
|
||||
dbg_step_into_func = false
|
||||
elseif event[1] == DBG_EVENT_GET_VALUE then
|
||||
local _, value = _debug_getlocal(event[2] + 3, event[3])
|
||||
for _, key in ipairs(event[4]) do
|
||||
if value == nil then
|
||||
value = "error: index nil value"
|
||||
break
|
||||
end
|
||||
value = value[key]
|
||||
end
|
||||
__sendvalue(value, event[2], event[3], event[4])
|
||||
__pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function debug.set_breakpoint(source, line)
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
bps = {}
|
||||
breakpoints[line] = bps
|
||||
end
|
||||
bps[source] = true
|
||||
end
|
||||
|
||||
function debug.remove_breakpoint(source, line)
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
return
|
||||
end
|
||||
bps[source] = nil
|
||||
end
|
||||
|
||||
function error(message, level)
|
||||
if is_debugging then
|
||||
__pause("exception", message)
|
||||
end
|
||||
__error(message, level)
|
||||
end
|
||||
@ -177,10 +177,8 @@ function inventory.set_description(invid, slot, description)
|
||||
inventory.set_data(invid, slot, "description", description)
|
||||
end
|
||||
|
||||
if enable_experimental then
|
||||
require "core:internal/maths_inline"
|
||||
end
|
||||
|
||||
require "core:internal/maths_inline"
|
||||
require "core:internal/debugging"
|
||||
asserts = require "core:internal/asserts"
|
||||
events = require "core:internal/events"
|
||||
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
local _ffi = ffi
|
||||
local _debug_getinfo = debug.getinfo
|
||||
|
||||
function crc32(bytes, chksum)
|
||||
local chksum = chksum or 0
|
||||
|
||||
@ -35,153 +38,6 @@ function parse_path(path)
|
||||
return string.sub(path, 1, index-1), string.sub(path, index+1, -1)
|
||||
end
|
||||
|
||||
local breakpoints = {}
|
||||
local dbg_steps_mode = false
|
||||
local dbg_step_into_func = false
|
||||
local hook_lock = false
|
||||
local current_func
|
||||
local current_func_stack_size
|
||||
|
||||
local __parse_path = parse_path
|
||||
local _debug_getinfo = debug.getinfo
|
||||
local _debug_getlocal = debug.getlocal
|
||||
local __pause = debug.pause
|
||||
local __error = error
|
||||
local __sethook = debug.sethook
|
||||
|
||||
-- 'return' hook not called for some functions
|
||||
-- todo: speedup
|
||||
local function calc_stack_size()
|
||||
local s = debug.traceback("", 2)
|
||||
local count = 0
|
||||
for i in s:gmatch("\n") do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local is_debugging = debug.is_debugging()
|
||||
if is_debugging then
|
||||
__sethook(function (e, line)
|
||||
if e == "return" then
|
||||
local info = _debug_getinfo(2)
|
||||
if info.func == current_func then
|
||||
current_func = nil
|
||||
end
|
||||
end
|
||||
if dbg_steps_mode and not hook_lock then
|
||||
hook_lock = true
|
||||
|
||||
if not dbg_step_into_func then
|
||||
local func = _debug_getinfo(2).func
|
||||
if func ~= current_func then
|
||||
return
|
||||
end
|
||||
if current_func_stack_size ~= calc_stack_size() then
|
||||
return
|
||||
end
|
||||
end
|
||||
current_func = func
|
||||
__pause("step")
|
||||
debug.pull_events()
|
||||
end
|
||||
hook_lock = false
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
return
|
||||
end
|
||||
local source = _debug_getinfo(2).source
|
||||
if not bps[source] then
|
||||
return
|
||||
end
|
||||
current_func = _debug_getinfo(2).func
|
||||
current_func_stack_size = calc_stack_size()
|
||||
__pause("breakpoint")
|
||||
debug.pull_events()
|
||||
end, "lr")
|
||||
end
|
||||
|
||||
local DBG_EVENT_SET_BREAKPOINT = 1
|
||||
local DBG_EVENT_RM_BREAKPOINT = 2
|
||||
local DBG_EVENT_STEP = 3
|
||||
local DBG_EVENT_STEP_INTO_FUNCTION = 4
|
||||
local DBG_EVENT_RESUME = 5
|
||||
local DBG_EVENT_GET_VALUE = 6
|
||||
local __pull_events = debug.__pull_events
|
||||
local __sendvalue = debug.__sendvalue
|
||||
debug.__pull_events = nil
|
||||
debug.__sendvalue = nil
|
||||
|
||||
function debug.get_pack_by_frame(func)
|
||||
local prefix, _ = __parse_path(_debug_getinfo(func, "S").source)
|
||||
return prefix
|
||||
end
|
||||
|
||||
function debug.pull_events()
|
||||
if not is_debugging then
|
||||
return
|
||||
end
|
||||
if not debug.is_debugging() then
|
||||
is_debugging = false
|
||||
__sethook()
|
||||
end
|
||||
local events = __pull_events()
|
||||
if not events then
|
||||
return
|
||||
end
|
||||
for i, event in ipairs(events) do
|
||||
if event[1] == DBG_EVENT_SET_BREAKPOINT then
|
||||
debug.set_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_RM_BREAKPOINT then
|
||||
debug.remove_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_STEP then
|
||||
dbg_steps_mode = true
|
||||
dbg_step_into_func = false
|
||||
elseif event[1] == DBG_EVENT_STEP_INTO_FUNCTION then
|
||||
dbg_steps_mode = true
|
||||
dbg_step_into_func = true
|
||||
elseif event[1] == DBG_EVENT_RESUME then
|
||||
dbg_steps_mode = false
|
||||
dbg_step_into_func = false
|
||||
elseif event[1] == DBG_EVENT_GET_VALUE then
|
||||
local _, value = _debug_getlocal(event[2] + 3, event[3])
|
||||
for _, key in ipairs(event[4]) do
|
||||
if value == nil then
|
||||
value = "error: index nil value"
|
||||
break
|
||||
end
|
||||
value = value[key]
|
||||
end
|
||||
__sendvalue(value, event[2], event[3], event[4])
|
||||
__pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function debug.set_breakpoint(source, line)
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
bps = {}
|
||||
breakpoints[line] = bps
|
||||
end
|
||||
bps[source] = true
|
||||
end
|
||||
|
||||
function debug.remove_breakpoint(source, line)
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
return
|
||||
end
|
||||
bps[source] = nil
|
||||
end
|
||||
|
||||
function error(message, level)
|
||||
if is_debugging then
|
||||
__pause("exception", message)
|
||||
end
|
||||
__error(message, level)
|
||||
end
|
||||
|
||||
-- Lua has no parallelizm, also _set_data does not call any lua functions so
|
||||
-- may be reused one global ffi buffer per lua_State
|
||||
local canvas_ffi_buffer
|
||||
@ -764,7 +620,7 @@ function __vc__error(msg, frame, n, lastn)
|
||||
if events then
|
||||
local frames = debug.get_traceback(1)
|
||||
events.emit(
|
||||
"core:error", msg,
|
||||
"core:error", msg,
|
||||
table.sub(frames, 1 + (n or 0), lastn and #frames-lastn)
|
||||
)
|
||||
end
|
||||
|
||||
@ -155,18 +155,18 @@ static int l_error_handler(lua_State* L) {
|
||||
}
|
||||
|
||||
int lua::call(State* L, int argc, int nresults) {
|
||||
int handler_pos = gettop(L) - argc;
|
||||
int handlerPos = gettop(L) - argc;
|
||||
pushcfunction(L, l_error_handler);
|
||||
insert(L, handler_pos);
|
||||
insert(L, handlerPos);
|
||||
int top = gettop(L);
|
||||
if (lua_pcall(L, argc, nresults, handler_pos)) {
|
||||
if (lua_pcall(L, argc, nresults, handlerPos)) {
|
||||
std::string log = tostring(L, -1);
|
||||
pop(L);
|
||||
remove(L, handler_pos);
|
||||
remove(L, handlerPos);
|
||||
throw luaerror(log);
|
||||
}
|
||||
int added = gettop(L) - (top - argc - 1);
|
||||
remove(L, handler_pos);
|
||||
remove(L, handlerPos);
|
||||
return added;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user