n 选择name和namewhat f 选择func S 选择source、short_src、what、linedefined和lastlinedefined l 选择currentline L 选择activelines u 选择nup、nparams和isvararg
下面这个函数演示了函数debug.getinfo的用法,它打印出了活跃栈的栈回溯:
1 2 3 4 5 6 7 8 9 10 11 12
funciton traceback() for level = 1, math.hugedo local info = debug.getinfo(level,"Sl") ifnot info then back end if info.what == "C"then print(string.format("%d\tC function",level)) else print(string.format("%d\t[%s]:%d",level, info.short_src, info.currentline)) end end end
functionfoo(a,b) local x dolocal c = a - b end local a = 1 whiletruedo local name ,value = debug.getlocal(1,a) ifnot name thenbreakend print(name , value) a = a + 1 end end
functiongetvarvalue(name,level,isenv) local value local found = false level = (level or1) + 1 --尝试局部变量 for i = 1 , math.hugedo lcoal n, v = debug,getlocal (level,i) ifnot n thenbreakend if n == name then value = v found = true end end if found thenreturn"local", value end --尝试非局部变量 local fun = debug.getinfo(level,"f").func for i = 1, math.hugedo local n,v = debug.getupvalue(func,i) ifnot n thenbreakend if n == name thenreturn"upvalue", v end end if isenv thenreturn"noenv"end--避免循环 --没找到;从环境中获取值 local _, env = getvarvalue("_ENV",level,true) if env then return"global" , env[name] else return"noenv" end end
用法如下:
1 2
> local a = 4; print(getvarvalue("a")) -- local 4 > a = "xx";print(getvarvalue("a")) -- global xx
localfunctionhook() local f = debug.getinfo(2,"f").func local count = Counters[f] if count == nilthen Counters[f] = 1 Names[f] = debug.getinfo(2,"Sn") else Counters[f] = count + 1 end end
local f = assert(loadfile(arg[1])) debug.sethook(hook,"c") f() debug.sethook()
最后一步是显示结果。 示例 获取一个函数的函数名
1 2 3 4 5 6 7 8 9 10 11 12
functiongetname(func) local n = Names[func] if n.what == "C"then return n.name end local lc = string.format("[%s]:%d",n.short_src, n.linedefined) if n.what ~= "main"and n.namewhat ~= ""then returnstring.format("%s (%s)",lc, n.name) else return lc end end
localdebug = require"debug" local steplimit = 1000 local count = 0 localfunctionsetp() count = count + 1 if count > steplimit then error("script uses too much CPU") end end
local validfunc = { [string.upper] = true, [string.lower] = true, ... -- 其他授权的函数 } localfunctionhook(event) if event == "call"then local info = debug.getinfo(2,"fn") ifnot validfunc[info.func] then error("calling bad function :" .. (info.name or"?")) end end count = count + 1 if count > steplimit then error("script uses too much CPU") end end
-- 加载代码段 local f = assert(loadfile(arg[1],"t",{})) debug.sethook(hook,"",100) f()