The debug Library

The debug library is powerful but slow and breaks encapsulation. Use it for debuggers, profilers, and tooling, never in normal code paths.

-- Introspection
local function where()
    local info = debug.getinfo(2, "Sl")          -- caller's source and current line
    return info.short_src .. ":" .. info.currentline
end
print(where())

local info = debug.getinfo(print)
print(info.what)                                 --> C

-- Local variables
local function inspect_locals()
    local i = 1
    while true do
        local name, value = debug.getlocal(2, i)
        if not name then break end
        print(name, value)
        i = i + 1
    end
end
local function demo() local x, y = 10, "hi"; inspect_locals() end
demo()

-- Upvalues
local counter = 0
local function inc() counter = counter + 1 end
print(debug.getupvalue(inc, 1))                  --> counter  0
debug.setupvalue(inc, 1, 100); inc(); print(counter)   --> 101

-- Hooks: "c" call, "r" return, "l" line, count
debug.sethook(function(event, line) io.write(event, ":", line or "", " ") end, "l")
local z = 1 + 1
debug.sethook()                                  -- remove the hook

print(debug.traceback("custom message", 1))
-- debug.getmetatable/setmetatable bypass __metatable protection; debug.getregistry; debug.upvalueid/upvaluejoin