EWD, which stands for Error Warning Debugging, is a Lua(JIT) module which aims to be a fundamental component of my methodology to deal with error handling, warning and debugging. At the moment, LuaJIT is the only target.
Aimed features:
- Ability to merge re-propagated stack traces.
- A propagating warning system similar to error callbacks.
- API to inspect call stack and data, e.g. at a breakpoint.
- Ability to analyze and estimate memory usage of the Lua state.
- Ability to dump data about the Lua state for deferred inspection, e.g. when a third-party encounters an error or a bug.
API
Warning System
Warnings can be propagated just like errors, at the exception that they do not interrupt execution. As for errors, the warning message doesn't have to be a string.
ewd.warn (message [, level])
Similar to error, but for warnings. The warning is propagated to the last enclosing cwpcall warning handler (or the root handler). The execution is not interrupted.
ewd.wassert (v [, message]) -> v [, message]
Similar to assert, but for warnings. Calls warn if v
is falsy.
ewd.wpcall (f, ...) -> ok, error or values...
Similar to pcall, but the error caught is propagated as a warning.
ewd.cwpcall (f, err_handler, warn_handler, ...) -> ok, error or values...
Similar to xpcall, but warn_handler
is a warning handler that will catch
warnings.
Callbacks:
err_handler(msg)
warn_handler(msg)
If err_handler
is the string "warn"
, the error will be propagated as a
warning to the handler above the current warning handler (warn_handler
).
Note: If the warning handler raises an error, it will be caught by the error handler.
ewd.warning_handler
The root warning handler called when there is no enclosing cwpcall.
The default handler writes to stderr. It can be replaced.
Debugging
ewd.rprint (max_depth, ...)
Format and print recursively the vararg values. A max_depth
of 0 will print
the values without recursion. Recursion will stop at direct cycles, but will
retraverse previous tables in the other cases.
ewd.rformat (max_depth, ...) -> string
Like rprint
, but will return a formatted string instead.
Interactive Debugging
ewd.debug()
Open a command-line interface similar to debug.debug()
. The function is not
reentrant.
Any Lua code can be executed, but partial code input is not supported.
By using one or multiple =
symbols as a prefix, the rprint
command will be
executed on the passed values with max_depth
set as the number of equal
symbols minus 1. I.e. ==
will result in one level of recursion.
The commands are executed into the debug environment, which inherits from the
global environment. This environment is shared for the lifetime of the ewd
module, i.e. for all ewd.debug()
breakpoints. It can, for example, be used to
create variables while debugging.
An empty command, i.e. by just pressing enter, will end debugging for this breakpoint and resume execution.
ewd.set_debugging (flag)
Enable or disable debugging, flag
is a boolean. When disabled, ewd.debug()
will have no effect. Debugging is enabled by default.
ewd.toggle_debugging ()
Toggle debugging.
ewd.set_debug_setup (f)
Set the setup function, f (env)
, which is called with the debug environment as
first argument at every breakpoint and every time the current stack frame
changes.
It can be used to display additional or customized informations, or to expose additional debug functions/commands.
The default setup function calls where()
.
Debug Environment
rprint, rformat (max_depth, ...)
Same as above.
where, w ()
Print trace and excerpt for the current stack frame.
trace, t ([radius])
Print trace for the current stack frame. A context radius
of 1
gives the previous and next frame.
excerpt, e ([radius])
Print excerpt for the current stack frame. A context radius
of 1
gives the previous and next line.
up, down ([n])
Move up or down in the call stack for n
frames. Default value for n
is 1.
Moving past the top or the bottom of the stack will just stop at both ends.
scope, s
Object to access variables, to read and write, at the current stack frame. It tries to simulate a scope by exposing named upvalues and locals in order, i.e. with shadowing.
env, globals, g
The function's environment table for the current stack frame.
upvalues, u ()
Print upvalues for the current stack frame.
locals, l ()
Print locals for the current stack frame. It prints all locals, even varargs or temporaries.
current, top ()
Return the level, relative to the caller, of the current stack frame (or the top).
func ()
Return the function at the current stack frame.
end_debugging, endd ()
Disable debugging and leave the current breakpoint.
Useful Patterns
==_G
: List fields present in the debug environment.==s
: List scope variables.