[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: LUA debugger and conditional breakpoints
- From: Benoit Germain <bgermain@...>
- Date: Thu, 11 Jul 2002 10:04:37 +0200
I am almost done with a debugger stub for lua 4.0 that sends information and
receives commands through a TCP socket.
I have implemented most of the usual features found in a debugger, but I am
now stuck with something that I don't know how to implement: evaluating
expressions containing local variables. This would enable expression
evaluation, conditional breakpoints and watch.
My implementation of breakpoints is as follows: a table in the registry
contains strings of lua code of the form "return exp" indexed by the
breakpoint's location stored as a string. The line hook rebuilds the string
from the ar information, looks up the entry in the breakpoints table, and
evaluates the condition. If the value on the stack is non-nil, the debugger
breaks. This works fine when the condition references globals or nothing
(unconditionl breakpoint being "return 1"), but this does not work with
conditions relating to local variables.
for example, if I have:
function f ( a )
print ( a )
f ( 3 )
f ( 4 )
f ( 5 )
and tell the debugger: break at line 2 when condition "return a == 4" is
it will never break, most probably because when the condition is evaluated
inside the line hook (with lua_dostring), it will interpret the "a"
reference as a reference to a global variable, hence the condition will
always be nil.
I had a look at ldb, and the author implements breakpoints in a similar
fashion, and talks about "simulated local environment". His breakpoints are
of the form "function dummy (args) block end", evaluated, then lua_ref'ed,
and when a breakpoints location is hit, the reference is read and the
function evaluated. The author also uses lua_beginblock() and
lua_endblock(), which seems 3.x-specific. What does it do ? I suppose it is
equivalent to the pair int top = lua_gettop(L) / lua_settop(L,top) ? I also
see that when evaluating an expression, ldb takes all locals of the current
context, and makes globals of them, saving the masked global's value
somewhere, and restores those values after the expression is evaluated. Is
there really no other means to access local values ? I will do the same if
it is the only way, but if there is another solution I am interested :-)