Introduction
Starting with version 3.2, Redis comes with a full Lua debugger that can be used to make writing complex Redis scripts a lot easier.
The LDB debugger for Redis Lua includes the following significant features:
-
It's a remote debugger that uses a server-client approach. The default client is redis-cli, while the Redis server serves as the debugging server. On the other hand, other clients can be created by following the server's primary protocol.
-
Every new debugging session is considered to be a forked session by default. It means that the server does not block while the Redis Lua script is being debugged, and it can be used for development or to run many debugging sessions in parallel. This also implies that all modifications are rolled back after the script debugging session is completed, allowing you to start a new debugging session with the same Redis data set.
-
On-demand, an alternate synchronous (non-forked) debugging approach is offered to keep changes to the dataset. The server blocks in this mode for the duration of the debugging session.
-
Step-by-step execution is supported.
-
Breakpoints can be static or dynamic.
-
Logging the debugged script into a debugger console is supported.
-
Variables in Lua are examined.
-
The script's Redis commands are being traced.
-
Redis and Lua's values are printed nicely.
- Infinite loops and detection of extended execution times, simulating a breakpoint.
Quick start
To use redis-cli to start an afresh debugging session, perform the following:
Write your script in a file using your favorite editor. Let's pretend you're editing your /tmp/script.lua Redis Lua script.
Begin your debugging session by:
./redis-cli --ldb --eval /tmp/script.lua
Note that you can supply key names and arguments to redis-cli using the —eval option, separated by a comma, as seen in the below example:
./redis-cli --ldb --eval /tmp/script.lua mykey some key , arg1 arg
You'll enter a special mode in which redis-cli stops accepting normal inputs and instead produces a help page and sends the debugging commands to Redis unchanged.
Only the following commands are not given to the Redis debugger:
- quit: This command will end the debugging session. It's the same as removing all breakpoints and rerunning the debugging command. Furthermore, the command will terminate redis-cli.
- Restart: the debugging session will begin with the new version of the script loaded from the file. So, after some debugging, a typical debugging cycle entails modifying the script and then calling restart to resume debugging with the new script changes.
-
help: this command is passed to the debugger, which prints a list of commands such as
lua debugger> help
Redis Lua debugger help:
[h]elp Show this help.
[n]ext Alias for step.
[c]continue Run till the next breakpoint.
[s]tep Run current line and then stop again.
[w]hole List all source code. Alias for 'list 1 1000000'.
[p]rint Show all the local variables.
[b]reak Show all breakpoints.
[t]race Show a backtrace.
[l]list List a source code around the current line.
[b]reak 0 Remove all breakpoints.
[r]edis <cmd> Execute a Redis command.
[b]reak <line> Add a breakpoint to a particular line.
[e]eval <code> Execute some Lua code.
[l]list [line] List the source code around the line.
where line = 0 means current position.
[a]abort Stop the execution of a script and in sync
mode dataset changes will be retained.
[p]rint <var> Show the value of some specified variable.
It can also show global vars KEYS and ARGV.
[b]reak -<line> Remove breakpoint from a particular line.
[m]axlen [len] Trim logged Redis replies and Lua var dumps to learn.
Specifying zero as <len> means unlimited.
Debugger functions that you can call from Lua scripts:
redis.debug() Produce logs in the console.
redis.breakpoint() would Stop execution if there were a breakpoint in the
next line of code.
When you first start the debugger, it will be in stepping mode. Before executing the script, pause at the first line that accomplishes something before running the script.
You normally call step from here to execute the line and go on to the next one. While you step, Redis will display all of the server's commands, as shown in the following example:
* Stopped at 1, stop reason = step over
-> 1 redis.call('ping')
lua debugger> step
<redis> ping
<reply> "+PONG"
* Stopped at 2, stop reason = step over
The <reply> and <redis> lines show the command issued by the line just executed and the server's response. It is worth noting that this happens in stepping mode. To avoid too much output, if you continue to execute the script until the next breakpoint, commands will not be spewed on the screen.