extract debugging code to internal/debugging module

This commit is contained in:
MihailRis 2025-10-31 23:18:26 +03:00
parent 0e2b203fb2
commit 284f24433c
4 changed files with 157 additions and 157 deletions

View 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

View File

@ -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"

View File

@ -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

View File

@ -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;
}