Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
5c4f4928
Commit
5c4f4928
authored
Nov 10, 2015
by
antirez
Browse files
Lua debugger: ability to show local vars content.
parent
5417217c
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/scripting.c
View file @
5c4f4928
...
...
@@ -1602,6 +1602,11 @@ char *ldbGetSourceLine(int line) {
return
ldb
.
src
[
idx
];
}
int
ldbIsBreakpoint
(
int
line
)
{
/* TODO: fixme. */
return
0
;
}
/* Expect a valid multi-bulk command in the debugging client query buffer.
* On success the command is parsed and returned as an array of SDS strings,
* otherwise NULL is returned and there is to read more buffer. */
...
...
@@ -1672,8 +1677,74 @@ void ldbList(int around, int context) {
}
}
/* Produce a debugger log entry representing the value of the Lua object
* currently on the top of the stack. */
void
ldbLogStackValue
(
lua_State
*
lua
)
{
int
t
=
lua_type
(
lua
,
-
1
);
sds
s
=
sdsnew
(
"<value> "
);
switch
(
t
)
{
case
LUA_TSTRING
:
s
=
sdscat
(
s
,
lua_tostring
(
lua
,
-
1
));
break
;
case
LUA_TBOOLEAN
:
s
=
sdscat
(
s
,
lua_toboolean
(
lua
,
-
1
)
?
"true"
:
"false"
);
break
;
case
LUA_TNUMBER
:
s
=
sdscatprintf
(
s
,
"%g"
,(
double
)
lua_tonumber
(
lua
,
-
1
));
break
;
case
LUA_TNIL
:
s
=
sdscat
(
s
,
"nil"
);
break
;
case
LUA_TTABLE
:
case
LUA_TFUNCTION
:
case
LUA_TUSERDATA
:
case
LUA_TTHREAD
:
case
LUA_TLIGHTUSERDATA
:
{
const
void
*
p
=
lua_topointer
(
lua
,
-
1
);
char
*
typename
=
"unknown"
;
if
(
t
==
LUA_TTABLE
)
typename
=
"table"
;
else
if
(
t
==
LUA_TFUNCTION
)
typename
=
"function"
;
else
if
(
t
==
LUA_TUSERDATA
)
typename
=
"userdata"
;
else
if
(
t
==
LUA_TTHREAD
)
typename
=
"thread"
;
else
if
(
t
==
LUA_TLIGHTUSERDATA
)
typename
=
"light-userdata"
;
s
=
sdscatprintf
(
s
,
"%s at %p"
,
typename
,
p
);
}
break
;
default:
s
=
sdscat
(
s
,
"?"
);
break
;
}
ldbLog
(
s
);
lua_pop
(
lua
,
1
);
}
/* Implements the "print" command of the Lua debugger. It scans for Lua
* var "varname" starting from the current stack frame up to the top stack
* frame. The first matching variable is printed. */
void
ldbPrint
(
lua_State
*
lua
,
lua_Debug
*
orig_ar
,
char
*
varname
)
{
lua_Debug
ar
;
int
l
=
0
;
/* Stack level. */
while
(
lua_getstack
(
lua
,
l
,
&
ar
)
!=
0
)
{
l
++
;
const
char
*
name
;
int
i
=
1
;
/* Variable index. */
while
((
name
=
lua_getlocal
(
lua
,
&
ar
,
i
))
!=
NULL
)
{
i
++
;
if
(
strcmp
(
varname
,
name
)
==
0
)
{
ldbLogStackValue
(
lua
);
return
;
}
else
{
lua_pop
(
lua
,
1
);
/* Discard the var name on the stack. */
}
}
}
ldbLog
(
sdsnew
(
"No such variable."
));
}
/* Read debugging commands from client. */
void
ldbRepl
(
void
)
{
void
ldbRepl
(
lua_State
*
lua
,
lua_Debug
*
ar
)
{
sds
*
argv
;
int
argc
;
...
...
@@ -1700,11 +1771,12 @@ void ldbRepl(void) {
/* Execute the command. */
if
(
!
strcasecmp
(
argv
[
0
],
"help"
))
{
ldbLog
(
sdsnew
(
"Redis Lua debugger help:"
));
ldbLog
(
sdsnew
(
"[s]tep
r
un current line and stop again."
));
ldbLog
(
sdsnew
(
"[n]ext
a
lias for step."
));
ldbLog
(
sdsnew
(
"[c]continue
r
un till next breakpoint."
));
ldbLog
(
sdsnew
(
"[l]list [line]
l
ist source code, around [line] if specified"
));
ldbLog
(
sdsnew
(
"[s]tep
R
un current line and stop again."
));
ldbLog
(
sdsnew
(
"[n]ext
A
lias for step."
));
ldbLog
(
sdsnew
(
"[c]continue
R
un till next breakpoint."
));
ldbLog
(
sdsnew
(
"[l]list [line]
L
ist source code, around [line] if specified"
));
ldbLog
(
sdsnew
(
" you can use another arg for context size."
));
ldbLog
(
sdsnew
(
"[p]rint <var> Show the value of the specified local variable."
));
ldbSendLogs
();
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"s"
)
||
!
strcasecmp
(
argv
[
0
],
"step"
)
||
!
strcasecmp
(
argv
[
0
],
"n"
)
||
!
strcasecmp
(
argv
[
0
],
"next"
))
{
...
...
@@ -1712,6 +1784,11 @@ ldbLog(sdsnew(" you can use another arg for context size."));
break
;
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"c"
)
||
!
strcasecmp
(
argv
[
0
],
"continue"
)){
break
;
}
else
if
(
argc
==
2
&&
(
!
strcasecmp
(
argv
[
0
],
"p"
)
||
!
strcasecmp
(
argv
[
0
],
"print"
)))
{
ldbPrint
(
lua
,
ar
,
argv
[
1
]);
ldbSendLogs
();
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"l"
)
||
!
strcasecmp
(
argv
[
0
],
"list"
)){
int
around
=
0
,
ctx
=
5
;
if
(
argc
>
1
)
around
=
atoi
(
argv
[
1
]);
...
...
@@ -1719,7 +1796,8 @@ ldbLog(sdsnew(" you can use another arg for context size."));
ldbList
(
around
,
ctx
);
ldbSendLogs
();
}
else
{
ldbLog
(
sdsnew
(
"Unknown Redis Lua debugger command."
));
ldbLog
(
sdsnew
(
"Unknown Redis Lua debugger command or "
"wrong number of arguments."
));
ldbSendLogs
();
}
...
...
@@ -1744,7 +1822,7 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
ldbLog
(
sdscatprintf
(
sdsempty
(),
"%d: %s"
,
(
int
)
ar
->
currentline
,
ldbGetSourceLine
(
ar
->
currentline
)));
ldbSendLogs
();
ldbRepl
();
ldbRepl
(
lua
,
ar
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment