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 includes the following functions:
| No. | Method & Purpose |
| --- | --- |
| 1. | **debug():** Enters an interactive user mode, running each string entered by the user. Using simple commands and other debugging settings, users can inspect global and local variables, change variable values, evaluate expressions, etc. Entering a string containing only "cont" ends this function, allowing the caller to continue execution. |
| 2. | **getfenv(object):** Returns the environment variable 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 containing 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 on the specified thread: level 0 is the current function (`getinfo` itself); level 1 is the function that called `getinfo` (unless it's a tail call, which is not counted in 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 at index `local` of the function at level `f` of the stack. This function is used not only to access explicitly defined local variables but also parameters, temporary variables, etc. |
| 6. | **getmetatable(value):** Pushes the metatable of the value at 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, a predefined table that can be used to store any Lua values that 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`. Variable names starting with '(' (open parenthesis) represent unnamed variables (code blocks with debug information removed). |
| 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: * **'`c`':** Calls the hook whenever Lua calls a function; * **'`r`':** Calls the hook whenever Lua returns from a function; * **'`l`':** Calls the hook whenever Lua enters a new line. |
| 11. | **setlocal ([thread,] level, local, value):** This function assigns `value` to the `local`-th local variable of the function at level `level` of the stack. If the variable does not exist, the function returns `nil`. If `level` is out of bounds, 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 the upvalue. |
| 14. | **traceback ([thread,] [message [, level]]):** If `message` is present and is not a string or `nil`, the function does nothing and returns `message` directly. Otherwise, it returns a traceback of the call stack. The optional string `message` is added to the beginning of the traceback. The optional number `level` specifies from which level of the stack to start the traceback (default is 1, i.e., where `traceback` was called). |
The table above lists the commonly used debugging functions. Next, we can look at some simple examples:
## Example
```lua
function myfunction ()
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
: ?
Stack trace end
In this example, we used the `traceback` and `getinfo` functions from the debug library. The `getinfo` function returns a table containing information about the function.
### Another Example
We often need to debug local variables within a function. We can use the `setupvalue` function to set these local variables. Here is an example:
## Example
```lua
function newCounter ()
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 this example, the counter increments by 1 each time it is called. We used the `getupvalue` function to view the current state of the local variables. We can set local variables to new values. In this example, before setting, the value of `n` was 2. We used the `setupvalue` function to set it to 10. Now, when we call the function, the output is 11 instead of 3.
* * *
## Debugging Types
* Command-line debugging
* Graphical user interface (GUI) debugging
Command-line debuggers include: RemDebug, clidebugger, ctrace, xdbLua, LuaInterface - Debugger, Rldb, ModDebug.
GUI debuggers include: SciTE, Decoda, ZeroBrane Studio, akdebugger, luaedit.
YouTip