Lua Debug
Lua provides a debug library for creating custom debuggers. Lua itself does not have a built-in debugger, but many developers have shared their Lua debugger code.
The debug library in Lua contains the following functions:
| No. | Method & Description |
|---|---|
| 1. | debug(): Enters an interactive mode with the user, running each string the user enters. Using simple commands and other debug settings, the user can inspect global and local variables, change variable values, evaluate expressions, and so on. |
| 2. | getfenv(object): Returns the environment of the object. |
| 3. | gethook(optional thread): Returns three values representing the thread hook settings: the current hook function, the current hook mask, and the current hook count. |
| 4. | getinfo ([thread,] f [, what]): Returns a table with information about a function. You can provide the function directly, or use a number f to represent it. The number f represents the function at the corresponding level of the call stack running on the specified thread: level 0 is the current function (getinfo itself); level 1 is the function that called getinfo (unless it is a tail call, which does not count on the stack); and so on. If f is a number greater than the number of active functions, getinfo returns nil. |
| 5. | debug.getlocal ([thread,] f, local): This function returns the name and value of the local variable with index local of the function at level f on the stack. This function is used not only to access explicitly defined local variables, but also formal parameters, temporary variables, etc. |
| 6. | getmetatable(value): Pushes the metatable of the value pointed to by the given index onto the stack. If the index is invalid, or the value has no metatable, the function returns 0 and does not push anything onto the stack. |
| 7. | getregistry(): Returns the registry table, which is a predefined table that can be used to save any Lua value C code wants to save. |
| 8. | getupvalue (f, up) This function returns the name and value of the up-th upvalue of function f. If the function does not have that upvalue, it returns nil. |
| 10. | sethook ([thread,] hook, mask [, count]): Sets a function as the hook function. The string mask and the number count determine when the hook will be called. The mask is a string composed of the following characters, each with its meaning:
|
| 11. | setlocal ([thread,] level, local, value): This function assigns value to the local-th local variable of the function at level level on the stack. If that variable does not exist, the function returns nil. If level is out of range, it throws an error. |
| 12. | setmetatable (value, table): Sets the metatable of value to table (which can be nil). Returns value. |
| 13. | setupvalue (f, up, value): This function sets value as the up-th upvalue of function f. If the function does not have that upvalue, it returns nil; otherwise, it returns the name of that upvalue. |
| 14. | traceback ([thread,] [message [, level]]): If message is present and is not a string or nil, the function returns message directly without doing anything else. Otherwise, it returns the stack traceback information of the call stack. The optional string message is added at the beginning of the stack traceback. The optional number level indicates which level of the stack to start tracing back from (default is 1, i.e., where traceback is called). |
The table above lists the debugging functions we commonly use. Next, we can look at some simple examples:
Example
print(debug.traceback("Stack trace"))
print(debug.getinfo(1))
print("Stack trace end")
return 10
end
myfunction ()
print(debug.getinfo(1))
Executing the above code produces the following output:
Stack trace stack traceback: test2.lua:2: in function 'myfunction' test2.lua:8: in main chunk [C]: ? table: 0054C6C8 Stack trace end
In the above example, we used the traceback and getinfo functions of the debug library. The getinfo function is used to return a table of function information.
Another example
We often need to debug local variables inside a function. We can use the setupvalue function to set these local variables. An example is as follows:
Example
local n = 0
local k = 0
return function ()
k = n
n = n + 1
return n
end
end
counter = newCounter ()
print(counter())
print(counter())
local i = 1
repeat
name, val = debug.getupvalue(counter, i)
if name then
print ("index", i, name, "=", val)
if(name == "n") then
debug.setupvalue (counter,2,10)
end
i = i + 1
end -- if
until not name
print(counter())
Executing the above code produces the following output:
1 2 index 1 k = 1 index 2 n = 2 11
In the above example, the counter increments by 1 each time it is called. In the example, we used the getupvalue function to view the current state of the local variable. We can set the local variable to a new value. In the example, before setting, the value of n is 2. Using the setupvalue function, we set it to 10. Now we call the function, and after execution the output is 11 instead of 3.
Debugging Types
- Command-line Debugging
- GUI Debugging
Command-line debuggers include: RemDebug, clidebugger, ctrace, xdbLua, LuaInterface - Debugger, Rldb, ModDebug.
GUI debuggers include: SciTE, Decoda, ZeroBrane Studio, akdebugger, luaedit.
Other extensions