English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Lua Debugging

Lua provides a debug library for creating our custom debuggers. Lua itself does not have an integrated debugger, but many developers have shared their Lua debugger code.

The Lua debug library includes the following functions:

Serial NumberMethod & Purpose
1.debug():

Enter a user interaction mode, running each string entered by the user. With simple commands and other debugging settings, users can inspect global and local variables, change variable values, calculate expressions, and so on.
Enter a string containing only 'cont' to end this function, so that the caller can continue running downwards.

2.getfenv(object):

Returns the environment variables of the object.

3.gethook(optional thread):

Returns three values representing the settings of thread hooks: 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 directly provide the function, or use a number 'f' to represent the function. The number 'f' represents the function at the corresponding level of the call stack of the specified thread: 0 level represents the current function (getinfo itself); 1 The level represents the function that called getinfo (except for tail calls, which are not counted in the stack); etc. If 'f' is a number larger 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' on the stack. This function is not only used to access explicitly defined local variables but also includes formal 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 if the value does not have a 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 that C code wants to save.

8.getupvalue (f, up)

This function returns the name and value of the upvalue at index 'up' of the function 'f'. If the function does not have that upvalue, it returns nil.
A variable name starting with '(' (open parenthesis) represents an anonymous variable (code block without debug information removed).

10.sethook ([thread,] hook, mask [, count]):

Set a function as a 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': A hook is called every time Lua calls a function;

  • 'r': A hook is called every time Lua returns from a function;

  • 'l': A hook is called every time 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 the level-th level on the stack. If there is no such variable, 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 to the up-th value of function f. If the function does not have that up-value, it returns nil; otherwise, it returns the name of that up-value.

14.traceback ([thread,] [message [, level]]):

If message is present and is not a string or nil, the function does nothing and returns the message directly. Otherwise, it returns the stack traceback information of the call stack. The optional string message can be added at the beginning of the stack traceback information. The optional numeric level indicates from which level of the stack to start the traceback (the default is 1 i.e., where traceback is called).

The table above lists our commonly used debugging functions, and next we can look at some simple examples:

function myfunction()
print(debug.traceback("Stack trace"))
print(debug.getinfo(1))
print("Stack trace end")
        return 10
end
myfunction()
print(debug.getinfo(1))

The output of the code above is as follows:

Stack trace
stack traceback:
    test2.lua:2: in function 'myfunction'
    test2.lua:8: in main chunk
    [C]: ?
table: 0054C6C8
Stack trace end

In this example, we use the traceback and getinfo functions from the debug library, where the getinfo function is used to return a table of function information.

Another example

We often need to debug local variables inside functions. We can use the getupvalue function to set these local variables. An example is as follows:

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())

The output of the code above is as follows:

1
2
index    1    k  =    1
index    2    n  =    2
11

In the above example, the counter will increment by itself each time it is called1. In the example, we used the getupvalue function to view the current state of the local variables. We can set the local variables to new values. In the example, the value of n before setting is 2, set it using the setupvalue function to 10. Now we call the function, and the output after execution is 11 Instead of 3.

Debugging Types

  • Command-line Debugging

  • Graphical Interface Debugging

Command-line debuggers include: RemDebug, clidebugger, ctrace, xdbLua, LuaInterface - Debugger, Rldb, ModDebug.

Graphical debuggers include: SciTE, Decoda, ZeroBrane Studio, akdebugger, luaedit.