Alright, if you got to this point it is likely that something doesn't quite work as expected in your script, or you're simply curious and want to learn new stuff. Either ways, let's get ahead, and see what's this about.
On Wikipedia there is a whole category about debugging, so perhaps it's worth using some tools developed for aiding with this process rather then using print()
and io.read()
statements scattered all around the code.
First thing first. We need to install our debugger, otherwise you won't be able to experiment alongside. All you need to do is type
luarocks install mobdebug
th -e "require('mobdebug').listen()"
In order to understand the different functionalities that MobDebug offers, we're going to debug, step by step, a simple Lua script.
(The script itself can be found at src/test.lua
, and it has been borrowed from remdebug's testing script.)
1 require('mobdebug').start()
2
3 local tab = {
4 foo = 1,
5 bar = 2
6 }
7
8 print("Start")
9
10 function bar()
11 print("In bar 1")
12 print("In bar 2")
13 end
14
15 for i = 1, 10 do
16 print("Loop")
17 bar()
18 tab.foo = tab.foo * 2
19 end
20
21 print("End")
Generally speaking, all we need to do is add
require('mobdebug').start()at the beginning of the script we want to debug.
So, let's cd
into src
and th
test.lua
.
run
, step
, over
and out
are the four commands that allow us to proceed with the execution of the code, tackling line after line. By typing help
withing the debugger session, we can see what their functions are.
run -- runs until next breakpoint
step -- runs until next line, stepping into function calls
over -- runs until next line, stepping over function calls
out -- runs until line after returning from current function
We can start with over
, step
, step
.
> over
Paused at file test.lua line 13
> step
Paused at file test.lua line 10
> step
Paused at file test.lua line 15
The first over
gets the program to print Start
.
The other two step
s don't have any corresponding output.
Our debugger is waiting for us at the beginning of the for
loop.
Let's skip to line 17
by setting a breakpoint and using run
.
To execute the code up to a specific line of a specific file we can use the breackpoint/run combination. The instruction to set a breakpoint works as follow
setb <file> <line> -- sets a breakpoint
To list all available breakpoints, we can write
listb -- lists breakpoints
To remove a breakpoint or all breakpoints
delb <file> <line> -- removes a breakpoint
delallb -- removes all breakpoints
Now we are at line 15
and, say, we'd like to skip to line 17
.
> 15 for i = 1, 10 do
16 print("Loop")
↳ 17 bar()
We are going to type setb test.lua 17
, or, since we don't link to other scripts, we can type steb - 17
.
> setb - 17
> run
Paused at file test.lua line 17
> listb
-: 17
run
makes the script print Loop
on screen.
Let's check now the value of some variables (even local ones!). We can do this with
eval <exp> -- evaluates expression on the current context and returns its value
or combining print()
with
exec <stmt> -- executes statement on the current context
exec
is really very powerful; I'll explain you why.Basically, it allows you to change the code live. You are allowed to put your hands inside the warm heart of the script that is currently running with all its local variables. This allows you to implement new functions (in someone's else code) way more easily (i.e. you don't have to read all the source code your collegue developed), since you'll find yourself in the exact same situation your new function will find itself when everything will be done.
For example, let's check the table tab
.
> eval tab
{bar = 2, foo = 1} --[[table: 0x06dfb9d0]]
If we would like to rely on Torch's pretty output format (which is advisable if you'd like visualise Tensors nicely), we type
> exec print(tab)
{
foo : 1
bar : 2
}
which is outputed on the terminal where the program is running (and not on the debugger interface).
Let's run
again a couple of times and see what's changes!
> run
Paused at file test.lua line 17
> eval tab
{bar = 2, foo = 2} --[[table: 0x06dfb9d0]]
> run
Paused at file test.lua line 17
> eval tab
{bar = 2, foo = 4} --[[table: 0x06dfb9d0]]
where run
gets the script to output In bar 1
, In bar 2
and Loop
twice.
As we can see, line 18
17 bar()
18 tab.foo = tab.foo * 2
19 end
doubles tab.foo
, which goes from 1
to 2
to 4
.
Now we can kill our breakpoint with
> delb - 17
> listb
>
Let's now run our code untill tab.foo
reaches the value 32
by setting a watch expression.