diff --git a/nse_debug.cc b/nse_debug.cc index 72aeb8be81..ad715fa566 100644 --- a/nse_debug.cc +++ b/nse_debug.cc @@ -1,35 +1,94 @@ #include "nse_debug.h" #include "output.h" +/* Print a Lua table. depth_limit is the limit on recursive printing of + subtables. */ +static void table_dump (lua_State *L, int i, int depth_limit) +{ + assert(lua_type(L, i) == LUA_TTABLE); + printf("{ "); + lua_pushvalue(L, i); + lua_pushnil(L); + while (lua_next(L, -2) != 0) { + value_dump(L, -2, depth_limit - 1); + printf(" = "); + value_dump(L, -1, depth_limit - 1); + printf(", "); + lua_pop(L, 1); + } + lua_pop(L, 1); + printf("}"); +} + +/* Print a Lua value. depth_limit controls the depth to which tables will be + printed recursively (0 for no recursion). */ +void value_dump (lua_State *L, int i, int depth_limit) +{ + int t = lua_type(L, i); + switch (t) + { + case LUA_TSTRING: /* strings */ + printf("'%s'", lua_tostring(L, i)); + break; + case LUA_TBOOLEAN: /* booleans */ + printf(lua_toboolean(L, i) ? "true" : "false"); + break; + case LUA_TNUMBER: /* numbers */ + printf("%g", lua_tonumber(L, i)); + break; + case LUA_TTABLE: + if (depth_limit > 0) + table_dump(L, i, depth_limit); + else + printf("table: %p", lua_topointer(L, i)); + break; + case LUA_TTHREAD: + case LUA_TFUNCTION: + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + printf("%s: %p", lua_typename(L, t), lua_topointer(L, i)); + break; + default: /* other values */ + printf("%s", lua_typename(L, t)); + break; + } +} + void stack_dump (lua_State *L) { int i, top = lua_gettop(L); for (i = 1; i <= top; i++) - { /* repeat for each level */ - int t = lua_type(L, i); + { printf("[%d, %d] = ", i, (-top + i - 1)); - switch (t) - { - case LUA_TSTRING: /* strings */ - printf("'%s'", lua_tostring(L, i)); - break; - case LUA_TBOOLEAN: /* booleans */ - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNUMBER: /* numbers */ - printf("%g", lua_tonumber(L, i)); - break; - case LUA_TTABLE: - case LUA_TTHREAD: - case LUA_TFUNCTION: - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - printf("%s: %p", lua_typename(L, t), lua_topointer(L, i)); - break; - default: /* other values */ - printf("%s", lua_typename(L, t)); - break; - } + value_dump(L, i, 0); printf("\n"); } } + +void lua_state_dump (lua_State *L) +{ + int top; + + printf("=== LUA STATE ===\n"); + + top = lua_gettop(L); + printf("=== STACK (height %d)\n", top); + stack_dump(L); + + printf("=== GLOBALS\n"); + table_dump(L, LUA_GLOBALSINDEX, 0); + printf("\n"); + + printf("=== REGISTRY\n"); + table_dump(L, LUA_REGISTRYINDEX, 0); + printf("\n"); + + printf("=== nmap.registry\n"); + lua_getglobal(L, "nmap"); + lua_getfield(L, -1, "registry"); + table_dump(L, -1, 1); + printf("\n"); + lua_pop(L, 2); + + assert(lua_gettop(L) == top); +} diff --git a/nse_debug.h b/nse_debug.h index 9e35818524..da6c2b4d31 100644 --- a/nse_debug.h +++ b/nse_debug.h @@ -2,12 +2,14 @@ #define NSE_DEBUG extern "C" { - #include "lua.h" - #include "lualib.h" - #include "lauxlib.h" +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" } +void value_dump(lua_State *L, int i, int depth_limit); void stack_dump(lua_State *L); +void lua_state_dump(lua_State *L); #endif