From 6bf8dd9a31fa3249915980007746a6d07a1c0bbd Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 13 Aug 2014 21:02:56 +0800 Subject: [PATCH] add debug command inject --- HISTORY.md | 1 + lualib/skynet.lua | 2 +- lualib/skynet/debug.lua | 62 ++++++++++++++++++++++++++++++++++++++- service/debug_console.lua | 37 +++++++++++++++++++++++ service/launcher.lua | 25 ---------------- 5 files changed, 100 insertions(+), 27 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 8f1a5ac2..af2d93c9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,6 +11,7 @@ Dev version * add skynet.harbor.queryname to query globalname * add cluster.proxy * add DEBUG command exit (send a message to lua service by DEBUG) +* add DEBUG command run (debug_console command inject) v0.5.2 (2014-8-11) ----------- diff --git a/lualib/skynet.lua b/lualib/skynet.lua index 563b0f26..6dd32a46 100644 --- a/lualib/skynet.lua +++ b/lualib/skynet.lua @@ -701,6 +701,6 @@ end -- Inject internal debug framework local debug = require "skynet.debug" -debug(skynet) +debug(skynet, dispatch_message) return skynet diff --git a/lualib/skynet/debug.lua b/lualib/skynet/debug.lua index 7e7ffa78..0f68dd1b 100644 --- a/lualib/skynet/debug.lua +++ b/lualib/skynet/debug.lua @@ -1,4 +1,8 @@ -return function (skynet) +local io = io +local table = table +local debug = debug + +return function (skynet, dispatch_func) local internal_info_func @@ -43,6 +47,62 @@ function dbgcmd.EXIT() skynet.exit() end +local function getupvaluetable(u, func, unique) + i = 1 + while true do + local name, value = debug.getupvalue(func, i) + if name == nil then + return + end + local t = type(value) + if t == "table" then + u[name] = value + elseif t == "function" then + if not unique[value] then + unique[value] = true + getupvaluetable(u, value, unique) + end + end + i=i+1 + end +end + +function dbgcmd.RUN(source, filename) + if filename then + filename = "@" .. filename + else + filename = "=(load)" + end + local output = {} + do + local function print(...) + local value = { ... } + for k,v in ipairs(value) do + value[k] = tostring(v) + end + table.insert(output, table.concat(value, "\t")) + end + local u = {} + local unique = {} + getupvaluetable(u, dispatch_func, unique) + getupvaluetable(u, skynet.register_protocol, unique) + local env = setmetatable( { print = print , _U = u }, { __index = _ENV }) + local func, err = load(source, filename, "bt", env) + if not func then + skynet.ret(skynet.pack(err)) + return + end + local ok, err = pcall(func) + if not ok then + table.insert(output, err) + end + + source, filename = nil + end + collectgarbage "collect" + skynet.ret(skynet.pack(table.concat(output, "\n"))) +end + local function _debug_dispatch(session, address, cmd, ...) local f = dbgcmd[cmd] assert(f, cmd) diff --git a/service/debug_console.lua b/service/debug_console.lua index 22cb7274..b627eb7a 100644 --- a/service/debug_console.lua +++ b/service/debug_console.lua @@ -36,6 +36,7 @@ local function dump_list(print, list) for _,v in ipairs(index) do dump_line(print, v, list[v]) end + print("OK") end local function split_cmdline(cmdline) @@ -92,6 +93,9 @@ skynet.start(function() socket.start(listen_socket , function(id, addr) local function print(...) local t = { ... } + for k,v in ipairs(t) do + t[k] = tostring(v) + end socket.write(id, table.concat(t,"\t")) socket.write(id, "\n") end @@ -115,6 +119,7 @@ function COMMAND.help() clearcache = "clear lua code cache", service = "List unique service", task = "task address : show service task detail", + inject = "inject address luascript.lua", } end @@ -144,3 +149,35 @@ end function COMMAND.service() return skynet.call("SERVICE", "lua", "LIST") end + +local function adjust_address(address) + if address:sub(1,1) ~= ":" then + address = bit32.replace( tonumber("0x" .. address), skynet.harbor(skynet.self()), 24, 8) + end + return address +end + +function COMMAND.exit(address) + skynet.send(adjust_address(address), "debug", "EXIT") +end + +function COMMAND.inject(address, filename) + address = adjust_address(address) + local f = io.open(filename, "rb") + if not f then + return "Can't open " .. filename + end + local source = f:read "*a" + f:close() + return skynet.call(address, "debug", "RUN", source, filename) +end + +function COMMAND.task(address) + address = adjust_address(address) + return skynet.call(address,"debug","TASK") +end + +function COMMAND.info(address) + address = adjust_address(address) + return skynet.call(address,"debug","INFO") +end diff --git a/service/launcher.lua b/service/launcher.lua index 58ae5f11..e4197035 100644 --- a/service/launcher.lua +++ b/service/launcher.lua @@ -28,26 +28,6 @@ function command.STAT() return list end -function command.INFO(_, handle) - handle = handle_to_address(handle) - if services[handle] == nil then - return - else - local result = skynet.call(handle,"debug","INFO") - return result - end -end - -function command.TASK(_, handle) - handle = handle_to_address(handle) - if services[handle] == nil then - return - else - local result = skynet.call(handle,"debug","TASK") - return result - end -end - function command.KILL(_, handle) handle = handle_to_address(handle) skynet.kill(handle) @@ -56,11 +36,6 @@ function command.KILL(_, handle) return ret end -function command.EXIT(_, handle) - handle = handle_to_address(handle) - skynet.send(handle, "debug", "EXIT") -end - function command.MEM() local list = {} for k,v in pairs(services) do