From c560c645e9d79df607c829de64b86d0513b8a08c Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 16 Nov 2015 13:58:17 +0100 Subject: [PATCH] Lua debugger: trace command implemented. --- src/scripting.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/scripting.c b/src/scripting.c index 8c345192..59a0d7a3 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -2145,6 +2145,26 @@ void ldbRedis(lua_State *lua, sds *argv, int argc) { lua_pop(lua,2); /* Discard the result and clean the stack. */ } +/* Implements "trace" command of the Lua debugger. It just prints a backtrace + * querying Lua starting from the current callframe back to the outer one. */ +void ldbTrace(lua_State *lua) { + lua_Debug ar; + int level = 0; + + while(lua_getstack(lua,level,&ar)) { + lua_getinfo(lua,"Snl",&ar); + if(strstr(ar.short_src,"user_script") == NULL) continue; + ldbLog(sdscatprintf(sdsempty(),"%s %s:", + (level == 0) ? "In" : "From", + ar.name ? ar.name : "top level")); + ldbLogSourceLine(ar.currentline); + level++; + } + if (level == 0) { + ldbLog(sdsnew(" Can't retrieve Lua stack.")); + } +} + /* Read debugging commands from client. */ void ldbRepl(lua_State *lua) { sds *argv; @@ -2190,6 +2210,7 @@ ldbLog(sdsnew("[b]reak Show all breakpoints.")); ldbLog(sdsnew("[b]reak Add a breakpoint to the specified line.")); ldbLog(sdsnew("[b]reak - Remove breakpoint from the specified line.")); ldbLog(sdsnew("[b]reak 0 Remove all breakpoints.")); +ldbLog(sdsnew("[t]race Show a backtrace.")); ldbLog(sdsnew("[e]eval Execute some Lua code (in a different callframe).")); ldbLog(sdsnew("[r]edis Execute a Redis command.")); ldbLog(sdsnew("[a]abort Stop the execution of the script. In sync")); @@ -2206,6 +2227,9 @@ ldbLog(sdsnew(" in the next line of code.")); break; } else if (!strcasecmp(argv[0],"c") || !strcasecmp(argv[0],"continue")){ break; + } else if (!strcasecmp(argv[0],"t") || !strcasecmp(argv[0],"trace")) { + ldbTrace(lua); + ldbSendLogs(); } else if (!strcasecmp(argv[0],"b") || !strcasecmp(argv[0],"break")) { ldbBreak(argv,argc); ldbSendLogs();