mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
Lua debugger: infinite loop detection.
This commit is contained in:
parent
1f35f2dd5a
commit
4b0b28b469
@ -1305,7 +1305,7 @@ void evalGenericCommand(client *c, int evalsha) {
|
|||||||
lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
|
lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
|
||||||
delhook = 1;
|
delhook = 1;
|
||||||
} else if (ldb.active) {
|
} else if (ldb.active) {
|
||||||
lua_sethook(server.lua,luaLdbLineHook,LUA_MASKLINE,0);
|
lua_sethook(server.lua,luaLdbLineHook,LUA_MASKLINE|LUA_MASKCOUNT,100000);
|
||||||
delhook = 1;
|
delhook = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2201,8 +2201,10 @@ void ldbMaxlen(sds *argv, int argc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read debugging commands from client. */
|
/* Read debugging commands from client.
|
||||||
void ldbRepl(lua_State *lua) {
|
* Return C_OK if the debugging session is continuing, otherwise
|
||||||
|
* C_ERR if the client closed the connection or is timing out. */
|
||||||
|
int ldbRepl(lua_State *lua) {
|
||||||
sds *argv;
|
sds *argv;
|
||||||
int argc;
|
int argc;
|
||||||
|
|
||||||
@ -2217,7 +2219,7 @@ void ldbRepl(lua_State *lua) {
|
|||||||
* client is no longer connected. */
|
* client is no longer connected. */
|
||||||
ldb.step = 0;
|
ldb.step = 0;
|
||||||
ldb.bpcount = 0;
|
ldb.bpcount = 0;
|
||||||
return;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
ldb.cbuf = sdscatlen(ldb.cbuf,buf,nread);
|
ldb.cbuf = sdscatlen(ldb.cbuf,buf,nread);
|
||||||
}
|
}
|
||||||
@ -2314,6 +2316,7 @@ ldbLog(sdsnew(" in the next line of code."));
|
|||||||
|
|
||||||
/* Free the current command argv if we break inside the while loop. */
|
/* Free the current command argv if we break inside the while loop. */
|
||||||
sdsfreesplitres(argv,argc);
|
sdsfreesplitres(argv,argc);
|
||||||
|
return C_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the core of our Lua debugger, called each time Lua is about
|
/* This is the core of our Lua debugger, called each time Lua is about
|
||||||
@ -2321,14 +2324,32 @@ ldbLog(sdsnew(" in the next line of code."));
|
|||||||
void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
|
void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
|
||||||
lua_getstack(lua,0,ar);
|
lua_getstack(lua,0,ar);
|
||||||
lua_getinfo(lua,"Sl",ar);
|
lua_getinfo(lua,"Sl",ar);
|
||||||
|
ldb.currentline = ar->currentline;
|
||||||
|
|
||||||
|
int bp = ldbIsBreakpoint(ldb.currentline) || ldb.luabp;
|
||||||
|
int timeout = 0;
|
||||||
|
|
||||||
|
/* Events outside our script are not interesting. */
|
||||||
if(strstr(ar->short_src,"user_script") == NULL) return;
|
if(strstr(ar->short_src,"user_script") == NULL) return;
|
||||||
|
|
||||||
ldb.currentline = ar->currentline;
|
/* Check if a timeout occurred. */
|
||||||
int bp = ldbIsBreakpoint(ldb.currentline) || ldb.luabp;
|
if (ar->event == LUA_HOOKCOUNT && ldb.step == 0 && bp == 0) {
|
||||||
|
mstime_t elapsed = mstime() - server.lua_time_start;
|
||||||
|
mstime_t timelimit = server.lua_time_limit ?
|
||||||
|
server.lua_time_limit : 5000;
|
||||||
|
if (elapsed >= timelimit) {
|
||||||
|
timeout = 1;
|
||||||
|
ldb.step = 1;
|
||||||
|
} else {
|
||||||
|
return; /* No timeout, ignore the COUNT event. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ldb.step || bp) {
|
if (ldb.step || bp) {
|
||||||
char *reason = "step over";
|
char *reason = "step over";
|
||||||
if (bp) reason = ldb.luabp ? "redis.breakpoint() called" :
|
if (bp) reason = ldb.luabp ? "redis.breakpoint() called" :
|
||||||
"break point";
|
"break point";
|
||||||
|
else if (timeout) reason = "timeout reached, infinite loop?";
|
||||||
ldb.step = 0;
|
ldb.step = 0;
|
||||||
ldb.luabp = 0;
|
ldb.luabp = 0;
|
||||||
ldbLog(sdscatprintf(sdsempty(),
|
ldbLog(sdscatprintf(sdsempty(),
|
||||||
@ -2336,7 +2357,14 @@ void luaLdbLineHook(lua_State *lua, lua_Debug *ar) {
|
|||||||
ldb.currentline, reason));
|
ldb.currentline, reason));
|
||||||
ldbLogSourceLine(ldb.currentline);
|
ldbLogSourceLine(ldb.currentline);
|
||||||
ldbSendLogs();
|
ldbSendLogs();
|
||||||
ldbRepl(lua);
|
if (ldbRepl(lua) == C_ERR && timeout) {
|
||||||
|
/* If the client closed the connection and we have a timeout
|
||||||
|
* connection, let's kill the script otherwise the process
|
||||||
|
* will remain blocked indefinitely. */
|
||||||
|
lua_pushstring(lua, "timeout during Lua debugging with client closing connection");
|
||||||
|
lua_error(lua);
|
||||||
|
}
|
||||||
|
server.lua_time_start = mstime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user