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
0d43a421
Commit
0d43a421
authored
Nov 10, 2015
by
antirez
Browse files
Lua debugger: breakpoints.
parent
44686bf9
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/redis-cli.c
View file @
0d43a421
...
...
@@ -490,6 +490,51 @@ static sds cliFormatReplyTTY(redisReply *r, char *prefix) {
return out;
}
int isColorTerm(void) {
char *t = getenv("TERM");
return t != NULL && strstr(t,"xterm") != NULL;
}
/* Helpe function for sdsCatColorizedLdbReply() appending colorize strings
* to an SDS string. */
sds sdscatcolor(sds o, char *s, size_t len, char *color) {
if (!isColorTerm()) return sdscatlen(o,s,len);
int bold = strstr(color,"bold") != NULL;
int ccode = 37; /* Defaults to white. */
if (strstr(color,"red")) ccode = 31;
else if (strstr(color,"red")) ccode = 31;
else if (strstr(color,"green")) ccode = 32;
else if (strstr(color,"yellow")) ccode = 33;
else if (strstr(color,"blue")) ccode = 34;
else if (strstr(color,"magenta")) ccode = 35;
else if (strstr(color,"cyan")) ccode = 36;
else if (strstr(color,"white")) ccode = 37;
o = sdscatfmt(o,"\033[%i;%i;49m",bold,ccode);
o = sdscatlen(o,s,len);
o = sdscat(o,"\033[0m");
return o;
}
/* Colorize Lua debugger status replies according to the prefix they
* have. */
sds sdsCatColorizedLdbReply(sds o, char *s, size_t len) {
char *color = "white";
if (strstr(s,"<redis>")) color = "green";
if (strstr(s,"<reply>")) color = "cyan";
if (strstr(s,"<error>")) color = "red";
if (strstr(s,"<value>")) color = "magenta";
if (isdigit(s[0])) {
char *p = s+1;
while(isdigit(*p)) p++;
if (*p == '*') color = "yellow"; /* Current line. */
else if (*p == '#') color = "bold"; /* Break point. */
}
return sdscatcolor(o,s,len,color);
}
static sds cliFormatReplyRaw(redisReply *r) {
sds out = sdsempty(), tmp;
size_t i;
...
...
@@ -504,7 +549,14 @@ static sds cliFormatReplyRaw(redisReply *r) {
break;
case REDIS_REPLY_STATUS:
case REDIS_REPLY_STRING:
out = sdscatlen(out,r->str,r->len);
if (r->type == REDIS_REPLY_STATUS && config.eval_ldb) {
/* The Lua debugger replies with arrays of simple (status)
* strings. We colorize the output for more fun if this
* is a debugging session. */
out = sdsCatColorizedLdbReply(out,r->str,r->len);
} else {
out = sdscatlen(out,r->str,r->len);
}
break;
case REDIS_REPLY_INTEGER:
out = sdscatprintf(out,"%lld",r->integer);
...
...
src/scripting.c
View file @
0d43a421
...
...
@@ -1602,8 +1602,39 @@ char *ldbGetSourceLine(int line) {
return
ldb
.
src
[
idx
];
}
/* Return true if there is a breakpoint in the specified line. */
int
ldbIsBreakpoint
(
int
line
)
{
/* TODO: fixme. */
int
j
;
for
(
j
=
0
;
j
<
ldb
.
bpcount
;
j
++
)
if
(
ldb
.
bp
[
j
]
==
line
)
return
1
;
return
0
;
}
/* Add the specified breakpoint. Ignore it if we already reached the max.
* Returns 1 if the breakpoint was added (or was already set). 0 if there is
* no space for the breakpoint or if the line is invalid. */
int
ldbAddBreakpoint
(
int
line
)
{
if
(
line
<=
0
||
line
>
ldb
.
lines
)
return
0
;
if
(
!
ldbIsBreakpoint
(
line
)
&&
ldb
.
bpcount
!=
LDB_BREAKPOINTS_MAX
)
{
ldb
.
bp
[
ldb
.
bpcount
++
]
=
line
;
return
1
;
}
return
0
;
}
/* Remove the specified breakpoint, returning 1 if the operation was
* performed or 0 if there was no such breakpoint. */
int
ldbDelBreakpoint
(
int
line
)
{
int
j
;
for
(
j
=
0
;
j
<
ldb
.
bpcount
;
j
++
)
{
if
(
ldb
.
bp
[
j
]
==
line
)
{
ldb
.
bpcount
--
;
memmove
(
ldb
.
bp
+
j
,
ldb
.
bp
+
j
+
1
,
ldb
.
bpcount
-
j
);
return
1
;
}
}
return
0
;
}
...
...
@@ -1668,10 +1699,10 @@ void ldbList(int around, int context) {
if
(
around
!=
0
&&
abs
(
around
-
j
)
>
context
)
continue
;
char
*
line
=
ldbGetSourceLine
(
j
);
int
mark
;
if
(
ldb
IsBreakpoint
(
j
)
)
mark
=
'
#
'
;
if
(
ldb
.
currentline
==
j
)
mark
=
'
*
'
;
else
mark
=
(
ldb
.
currentline
==
j
)
?
'
*
'
:
':'
;
mark
=
ldb
IsBreakpoint
(
j
)
?
'
#
'
:
':'
;
sds
thisline
=
sdscatprintf
(
sdsempty
(),
"%d%c %s"
,
j
,
mark
,
line
);
ldbLog
(
thisline
);
}
...
...
@@ -1723,8 +1754,9 @@ void ldbLogStackValue(lua_State *lua) {
/* 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
)
{
void
ldbPrint
(
lua_State
*
lua
,
char
*
varname
)
{
lua_Debug
ar
;
int
l
=
0
;
/* Stack level. */
while
(
lua_getstack
(
lua
,
l
,
&
ar
)
!=
0
)
{
l
++
;
...
...
@@ -1743,8 +1775,52 @@ void ldbPrint(lua_State *lua, lua_Debug *orig_ar, char *varname) {
ldbLog
(
sdsnew
(
"No such variable."
));
}
/* Implements the break command to list, add and remove breakpoints. */
void
ldbBreak
(
sds
*
argv
,
int
argc
)
{
if
(
argc
==
1
)
{
if
(
ldb
.
bpcount
==
0
)
{
ldbLog
(
sdsnew
(
"No breakpoints set. Use 'b <line>' to add one."
));
return
;
}
else
{
ldbLog
(
sdscatfmt
(
sdsempty
(),
"%i breakpoints set:"
,
ldb
.
bpcount
));
int
j
;
for
(
j
=
0
;
j
<
ldb
.
bpcount
;
j
++
)
{
ldbLog
(
sdscatfmt
(
sdsempty
(),
"%i# %s"
,
ldb
.
bp
[
j
],
ldbGetSourceLine
(
ldb
.
bp
[
j
])));
}
}
}
else
{
int
j
;
for
(
j
=
1
;
j
<
argc
;
j
++
)
{
char
*
arg
=
argv
[
j
];
long
line
;
if
(
!
string2l
(
arg
,
sdslen
(
arg
),
&
line
))
{
ldbLog
(
sdscatfmt
(
sdsempty
(),
"Invalid argument:'%s'"
,
arg
));
}
else
{
if
(
line
==
0
)
{
ldb
.
bpcount
=
0
;
ldbLog
(
sdsnew
(
"All breakpoints removed."
));
}
else
if
(
line
>
0
)
{
if
(
ldb
.
bpcount
==
LDB_BREAKPOINTS_MAX
)
{
ldbLog
(
sdsnew
(
"Too many breakpoints set."
));
}
else
if
(
ldbAddBreakpoint
(
line
))
{
ldbList
(
line
,
1
);
}
else
{
ldbLog
(
sdsnew
(
"Wrong line number."
));
}
}
else
if
(
line
<
0
)
{
if
(
ldbDelBreakpoint
(
line
))
ldbLog
(
sdsnew
(
"Breakpoint removed."
));
else
ldbLog
(
sdsnew
(
"No breakpoint in the specified line."
));
}
}
}
}
}
/* Read debugging commands from client. */
void
ldbRepl
(
lua_State
*
lua
,
lua_Debug
*
ar
)
{
void
ldbRepl
(
lua_State
*
lua
)
{
sds
*
argv
;
int
argc
;
...
...
@@ -1777,6 +1853,10 @@ ldbLog(sdsnew("[c]continue Run till next breakpoint."));
ldbLog
(
sdsnew
(
"[l]list [line] List 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."
));
ldbLog
(
sdsnew
(
"[b]eark Show all breakpoints."
));
ldbLog
(
sdsnew
(
"[b]eark <line> Add a breakpoint to the specified line."
));
ldbLog
(
sdsnew
(
"[b]eark -<line> Remove breakpoint from the specified line."
));
ldbLog
(
sdsnew
(
"[b]eark 0 Remove all breakpoints."
));
ldbSendLogs
();
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"s"
)
||
!
strcasecmp
(
argv
[
0
],
"step"
)
||
!
strcasecmp
(
argv
[
0
],
"n"
)
||
!
strcasecmp
(
argv
[
0
],
"next"
))
{
...
...
@@ -1784,10 +1864,13 @@ ldbLog(sdsnew("[p]rint <var> Show the value of the specified local variable.")
break
;
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"c"
)
||
!
strcasecmp
(
argv
[
0
],
"continue"
)){
break
;
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"b"
)
||
!
strcasecmp
(
argv
[
0
],
"break"
)){
ldbBreak
(
argv
,
argc
);
ldbSendLogs
();
}
else
if
(
argc
==
2
&&
(
!
strcasecmp
(
argv
[
0
],
"p"
)
||
!
strcasecmp
(
argv
[
0
],
"print"
)))
{
ldbPrint
(
lua
,
ar
,
argv
[
1
]);
ldbPrint
(
lua
,
argv
[
1
]);
ldbSendLogs
();
}
else
if
(
!
strcasecmp
(
argv
[
0
],
"l"
)
||
!
strcasecmp
(
argv
[
0
],
"list"
)){
int
around
=
0
,
ctx
=
5
;
...
...
@@ -1816,13 +1899,14 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
lua_getinfo
(
lua
,
"Sl"
,
ar
);
if
(
strstr
(
ar
->
short_src
,
"user_script"
)
==
NULL
)
return
;
if
(
ldb
.
step
)
{
if
(
ldb
.
step
||
ldbIsBreakpoint
(
ar
->
currentline
)
)
{
ldb
.
currentline
=
ar
->
currentline
;
ldb
.
step
=
0
;
ldbLog
(
sdscatprintf
(
sdsempty
(),
"%d: %s"
,
(
int
)
ar
->
currentline
,
ldbGetSourceLine
(
ar
->
currentline
)));
int
mark
=
ldbIsBreakpoint
(
ldb
.
currentline
)
?
'#'
:
'*'
;
ldbLog
(
sdscatprintf
(
sdsempty
(),
"%d%c %s"
,
(
int
)
ar
->
currentline
,
mark
,
ldbGetSourceLine
(
ar
->
currentline
)));
ldbSendLogs
();
ldbRepl
(
lua
,
ar
);
ldbRepl
(
lua
);
}
}
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