Debugging and Profiling

49.1 Debugging

Print debugging with inspect.lua or pl.pretty.dump. Use debug.traceback() in xpcall handlers.

Debuggers: VS Code + "Local Lua Debugger" (tomblind) or EmmyLua debugger, ZeroBrane Studio (MobDebug, including remote debugging of games), mobdebug for remote debugging, nvim-dap + one-small-step-for-vimkind (Neovim plugins), the LÖVE debugger, Roblox Studio's debugger.

require("mobdebug").start()   -- connect to ZeroBrane Studio's debugger server

49.2 Profiling

Profilers: LuaJIT's built-in profiler (luajit -jp=vl script.lua, jit.p), ProFi, luatrace, jprof (LÖVE), Neovim :Lazy profile, Roblox MicroProfiler, and perf + LuaJIT perf maps.

Memory: collectgarbage("count") snapshots, lua-memprof, LuaJIT -jdump/memory profilers.

-- Simple timing
local start = os.clock()
for i = 1, 1e7 do local _ = i * 2 end
print(("elapsed: %.3f s"):format(os.clock() - start))

-- Hook-based sampling profiler sketch
local counts = {}
debug.sethook(function()
    local info = debug.getinfo(2, "Sl")
    if info then
        local key = info.short_src .. ":" .. (info.currentline or 0)
        counts[key] = (counts[key] or 0) + 1
    end
end, "", 1000)                -- every 1000 VM instructions
-- run workload...
debug.sethook()