From 284f24433c15fe3e6fca24468b418f7885f8be0a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 Oct 2025 23:18:26 +0300 Subject: [PATCH] extract debugging code to internal/debugging module --- res/modules/internal/debugging.lua | 146 +++++++++++++++++++++++++ res/scripts/stdlib.lua | 6 +- res/scripts/stdmin.lua | 152 +-------------------------- src/logic/scripting/lua/lua_util.cpp | 10 +- 4 files changed, 157 insertions(+), 157 deletions(-) create mode 100644 res/modules/internal/debugging.lua diff --git a/res/modules/internal/debugging.lua b/res/modules/internal/debugging.lua new file mode 100644 index 00000000..cef40202 --- /dev/null +++ b/res/modules/internal/debugging.lua @@ -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 diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 3f732e07..cb25150b 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -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" diff --git a/res/scripts/stdmin.lua b/res/scripts/stdmin.lua index 4e01e22a..783e054e 100644 --- a/res/scripts/stdmin.lua +++ b/res/scripts/stdmin.lua @@ -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 diff --git a/src/logic/scripting/lua/lua_util.cpp b/src/logic/scripting/lua/lua_util.cpp index 401255c7..a09f5086 100644 --- a/src/logic/scripting/lua/lua_util.cpp +++ b/src/logic/scripting/lua/lua_util.cpp @@ -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; }