Lua-debugger makes lua virtual machine capable of single-step debugging by adding a debugging server. Instead of using Lua's hook machanism, we created a new OP_INTERRUPT instruction, and inject it into the proper position of the instruction list when a breakpoint is set.
- Download lua 5.3.x source code.
- Replace original lua source files with files in directoy src.
- Recompile lua(make linux).
To enable the function of debugging, it is recommended that first all your modules, and then invoke
debug.startserver()
then, when the application starts, the screen may look like this:
Lua VM paused at print.lua:21
19 end
20
-> 21 debug.startserver()
22 foo()
23
24
It means the virtual machine has been paused at startserver(), and then you can start debugging with the supplied commands.
Start the debugging server.
mode
: 'i' for interactive mode, 'f' for foreground mode, 'b' for background mode.addr
: listen IP address.
The server can be run in 3 different modes:
-
#####Interactive mode The virtual machine will be paused and commands will be received and processed through console(stdin and stdout).
Similar to interactive mode, but will listen on port 7609 and process commands thought TCP connection. Whenever the connection is broken, the lua program will exit.
Listen on port 7609 without pausing the virtual machine. Debugger client connects it, sends command pause
to explicitly pause the virtual machine. If the connection is broken, all breakpoints will be removed and the virtual machine continues.
0 if succeeds, otherwise an errno defined by POSIX.
Pause the virtual machine. This is a light-weight solution for conditional breakpoints, like this:
for i = 1, 1000000 do
if i == 654321 then
debug.pause()
end
end
Repeat the previous command.
Pause the Lua virutal machine. This command can only be used in backgroup mode, and only when the virtual machine is running.
Continue the lua virtual machine.
List source code.
> list frame.lua 10
10 local function f3()
11 f2()
12 end
13
-> 14 debug.startserver()
15 f3()
16
17
> list
<EOF>
> list frame.lua
1
2 local function f1()
3 x = x + 1
4 end
5
6 local function f2()
7 f1()
8 end
9
10 local function f3()
Print variables' values.
> print i1 i2
i1 = 10
i2 = 20
> print b1 b2
b1 = true
b2 = false
> print s
s = 'string'
> print t
t = (0x555b3b8f3170, sizearray=0, sizenode=4){
--node
['a'] = 1,
['b'] = 2,
['c'] = (0x555b3b8f1a70, sizearray=0, sizenode=4){},
}
> print t.c
t.c = (0x555b3b8f1a70, sizearray=0, sizenode=4){
--node
['cc'] = 3,
['bb'] = 2,
['aa'] = 1,
}
> print foo
foo = function
Show information about breakpoints|arguments|local-variables|up-values. info breaks|args|locals|upvals
Set a breakpoint.
> break 10
breakpoint #1 set at break.lua:10
> break other.lua 20
breakpoint #2 set at other.lua:10
Set a breakpoint which will only be triggered once.
Enable breakpoints(or other objects, in the future).
> enable breaks 1 2
disabled 2 breakpoint(s)
> enable breaks
disabled 3 breakpoint(s)
Disable breakpoints(or other objects, in the future).
> disable breaks 1 2
disabled 2 breakpoint(s)
> disable breaks
disabled 3 breakpoint(s)
Delete breakpoints(or other objects, in the future).
> delete breaks 1 2
deleted 2 breakpoint(s)
> disable breaks
deleted 3 breakpoint(s)
Show the stack.
> backtrace
-> frame.lua:3: in upvalue 'f1'
frame.lua:7: in upvalue 'f2'
frame.lua:11: in local 'f3'
frame.lua:15: in main chunk
[C]: in ?
Switch the current debugging frame.
> frame 1
in "frame.lua":
5
6 local function f2()
-> 7 f1()
8 end
9
10 local function f3()
11 f2()
12 end
13
14 debug.startserver()
> frame 4
unable to enter C-frame
Step forward by one line (skipping over functions).
Step forward by one line (into functions).
Finish the current call.
Keep running until jump out of the current loop.
Quit the debugging.
- Currently it can only be run on *nix systems.