feat(lua): Python-style traceback + locals capture#448
Conversation
Why: Lua scripts on Wippy had no way to capture a stack trace with local variables — only a bare debug.traceback string with no locals, and even that was unavailable because SkipOpenLibs excluded the debug library entirely. This adds Python-style traceback + locals capture, on demand, for debugging and error handlers. What: - Expose a read-only debug subset as a cached global (traceback, getinfo, getlocal, getupvalue); strip setlocal/setmetatable/setupvalue and getmetatable (the last bypasses __metatable, a sandbox hole). - Add the traceback module (runtime/lua/modules/traceback) with format(level, opts) and frames(level, opts): structured frames carrying locals and upvalues, with cycle detection and depth/locals/upvalues/max_value_len/ max_table_depth options. Frames that panic under post-recover conditions are skipped instead of aborting the trace. - Register traceback as a core ambient module (require-able + global). - Bump github.com/wippyai/go-lua to pick up xpcall catching errors under direct PCall/DoString and inspect.GetStackFrame now capturing upvalues, both prerequisites for throw-site capture from an xpcall handler.
|
will be kept for 2.0.0 update of go lua since it already has some pcall work |
wolfy-j
left a comment
There was a problem hiding this comment.
Blocking release review:\n\n1. This depends on wippyai/go-lua#32, which is still open, via a pseudo-version. Merge and tag that prerequisite before Runtime consumes it.\n2. The claimed read-only surface is not actually read-only: debug.getlocal, debug.getupvalue, and traceback.frames return live table/userdata references from caller frames. A callee can mutate a caller/upvalue table even though the setter functions were removed. Keep introspection internal and return bounded snapshots instead.\n3. Formatting is not memory-bounded. max_value_len caps individual strings and max_table_depth caps depth, but table width and total output are unlimited; one wide local table can exhaust the process. Add entry and total-byte caps and tests.\n\nThe feature direction is useful, but it should not ship as an ambient debug capability with mutable references and unbounded output.
Python-style stack-trace + locals capture for Wippy Lua scripts, on demand.
Why
Lua scripts had no way to capture a stack trace with local variables — only a bare
debug.tracebackstring with no locals, and even that was unavailable becauseSkipOpenLibsexcluded thedebuglibrary entirely.What
debugsubset as a cached global (cached_libs.go):traceback,getinfo,getlocal,getupvalue. Stripped:setlocal,setmetatable,setupvalue, andgetmetatable(the last bypasses__metatable— a sandbox hole).tracebackmodule (runtime/lua/modules/traceback):traceback.format(level, opts)— formatted multi-line string (Pythontraceback.format_excstyle).traceback.frames(level, opts)— structured frames withlocalsandupvalues.depth,locals,upvalues,max_value_len,max_table_depth.core_modules.go) —require("traceback")and global.Usage
Dependencies
Bumps
github.com/wippyai/go-luato a pre-release commit (wippyai/go-lua#32) for two prerequisites:xpcallcatching errors under directPCall/DoString, andinspect.GetStackFramecapturing upvalues. Once wippyai/go-lua#32 merges and tags a release, the pseudo-version can be replaced with the tag.Testing
make test-runtime,make lint, gofmt, vet — green.Sample output (xpcall throw-site capture)
No visual/UI changes (runtime-only feature).