skynet inject address file.lua

 

inject d test/inject_fuck.lua  -- d 是服务的 handle

 

拿 simpledb.lua 举例,修改如下

 1 local skynet = require "skynet"
 2 require "skynet.manager"    -- import skynet.register
 3 local db = {}
 4 
 5 local command = {}
 6 
 7 local i = 13
 8 local str = "abc"
 9 local t = {}
10 
11 function command.fuck()
12     return i, str, t
13 end
14 
15 skynet.info_func(function()
16     return command.fuck()
17 end)
18 
19 function command.GET(key)
20     return db[key]
21 end
22 
23 function command.SET(key, value)
24     local last = db[key]
25     db[key] = value
26     return last
27 end
28 
29 skynet.start(function()
30     skynet.dispatch("lua", function(session, address, cmd, ...)
31         local f = command[string.upper(cmd)]
32         if f then
33             skynet.ret(skynet.pack(f(...)))
34         else
35             error(string.format("Unknown command %s", tostring(cmd)))
36         end
37     end)
38     skynet.register "SIMPLEDB"
39 end)

添加了 fuck 函数,并设置 info_func。

设置 info_func 主要用来在 debug console 中方便用 info d 来查看 inject 的结果

 

下面是 inject_fuck.lua

 1 if not _P then
 2     print "inject error!"
 3     return
 4 end
 5 
 6 local function getuv(f) 
 7     local i = 1
 8     local ups = {}
 9     while true do
10         local name, value = debug.getupvalue(f, i)
11         if not name then
12             break
13         end
14         ups[name] = { i, value }
15         i = i + 1
16     end
17     return ups
18 end
19 
20 local function uvjoin(f, old_f, old_uv)
21     local i = 1
22     while true do
23         local name, value = debug.getupvalue(f, i)
24         if not name then
25             break
26         end
27         if old_uv[name] then
28             debug.upvaluejoin(f, i, old_f, old_uv[name][1])
29         end
30         i = i + 1
31     end
32 end
33 
34 
35 local command = _P.lua.command
36 
37 local func = command.fuck
38 local old_uv = getuv(func)
39 for k,v in pairs(old_uv) do
40     print(k,v[2])
41 end
42 
43 print("  ---  ")
44 
45 local t
46 local i
47 local str
48 function command.fuck()
49     return str, t, i
50 end
51 
52 uvjoin(command.fuck, func, old_uv)
53 -- debug.setupvalue( command.fuck, 1, 35 )

1. 取出原 fuck 函数的所有 upvalue

2. 然后关联到新的 fuck 函数

 

_P 内存的 key/value 其实就是 skynet.lua 里 14 行 proto 中的 name 和 dispatch 的 upvalue

 1 local c = require "skynet.core"
 2 local tostring = tostring
 3 local tonumber = tonumber
 4 local coroutine = coroutine
 5 local assert = assert
 6 local pairs = pairs
 7 local pcall = pcall
 8 
 9 local profile = require "profile"
10 
11 local coroutine_resume = profile.resume
12 local coroutine_yield = profile.yield
13 
14 local proto = {}
15 local skynet = {
16     -- read skynet.h
17     PTYPE_TEXT = 0,
18     PTYPE_RESPONSE = 1,
19     PTYPE_MULTICAST = 2,
20     PTYPE_CLIENT = 3,
21     PTYPE_SYSTEM = 4,
22     PTYPE_HARBOR = 5,
23     PTYPE_SOCKET = 6,
24     PTYPE_ERROR = 7,
25     PTYPE_QUEUE = 8,    -- used in deprecated mqueue, use skynet.queue instead
26     PTYPE_DEBUG = 9,
27     PTYPE_LUA = 10,
28     PTYPE_SNAX = 11,
29 }
30 
31 ---

 

再看 simpledb.lua 的例子,文件中 disptch 的 upvalue 有两个,command 和 skynet

所以 _P.lua.command 就是文件中的 command,_P.lua.skynet 就是 skynet

 

在 debug console 用 inject 命令时要格外小心。。

 

posted on 2017-03-17 14:20  明天有风吹  阅读(1549)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园