Lua function call trace (debugging aid)
Posted: 11 Feb 2008, 21:22
I just whipped this up because I needed it for debugging, and maybe someone else finds it useful too. Basically what it does is log every Lua function that gets called and write it to a text file.
Just drop this piece of code into your LuaUI/main.lua file at the top:
Then run Spring, and when you're done, view the luaui_log.txt file in your Spring directory. It logs a lot of calls, though, so make sure you only activate this when you need it because it's slow. Just comment out the last line by putting "--" in front of it to disable. Performance could probably be increased by writing it in C, but it's just a debugging aid, so what...
As an example of what this produces:
Pretty interesting to see what's going on in LuaUI, actually. I already found a bug in the widget handler that I wasn't even looking for just by inspecting these traces.
Theoretically this would also work for synced Lua code, but that runs in a different Lua context which has the necessary libraries (io and debug) disabled, so that would require a recompile of Spring.exe.
Anyway, this is just scratching the surface of the debug library; this stuff is really powerful. It would be possible to implement a full-blown Lua debugger within Spring so you could at any time break into your script, examine its variables, single-step through your code and so on. Someone just needs to take the time to write it
Just drop this piece of code into your LuaUI/main.lua file at the top:
Code: Select all
function CreateStackTraceHook()
local prefix = ""
local fp = assert(io.open("luaui_log.txt", "w"))
return function(event)
local info = debug.getinfo(2, "S")
if (info.what == "C") then return end -- do not log C functions
if (event == "call") then
local info2 = debug.getinfo(2, "n")
local src = info.short_src
local name = info2.name or ""
local line = info.linedefined
fp:write(prefix .. src .. "(" .. line .. "): " .. name .. "\n")
prefix = prefix .. " "
elseif (event == "return" or event == "tail return") then
prefix = string.sub(prefix, 3)
end
end
end
debug.sethook(CreateStackTraceHook(), "cr") -- hook call and return events
As an example of what this produces:
Code: Select all
[string "LuaUI/utils.lua"](49): include
[string "LuaUI/setupdefs.lua"](0):
[string "LuaUI/utils.lua"](49): include
[string "LuaUI/savetable.lua"](0):
[string "LuaUI/utils.lua"](49): include
[string "LuaUI/debug.lua"](0):
[string "LuaUI/utils.lua"](49): include
[string "LuaUI/fonts.lua"](0):
[string "LuaUI/fonts.lua"](415): UseFont
[string "LuaUI/fonts.lua"](362): LoadFont
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](80): HaveFontFiles
[string "LuaUI/fonts.lua"](120): LoadFontSpecs
[string "LuaUI/Fonts/FreeMonoBold_12.lua"](0): chunk
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](70): print
[string "LuaUI/fonts.lua"](147): MakeDisplayLists
[string "LuaUI/fonts.lua"](152):
[string "LuaUI/fonts.lua"](152):
[string "LuaUI/fonts.lua"](152):
[string "LuaUI/fonts.lua"](152):
[string "LuaUI/fonts.lua"](152):
[string "LuaUI/fonts.lua"](152):
(....lots of stuff snipped...)
Theoretically this would also work for synced Lua code, but that runs in a different Lua context which has the necessary libraries (io and debug) disabled, so that would require a recompile of Spring.exe.
Anyway, this is just scratching the surface of the debug library; this stuff is really powerful. It would be possible to implement a full-blown Lua debugger within Spring so you could at any time break into your script, examine its variables, single-step through your code and so on. Someone just needs to take the time to write it
