localfunctionsetbreakpoint(where, line) if (type(where) ~= "function"andtype(where) ~= "string") or ( line andtype(line) ~= "number") then io.write("invalid parameter\n") returnnil end
iftype(where) == "function"then return setfuncbp(where, line) else-- "string" return setnamebp(where, line) end end
localfunctionsetnamebp(name, line) local s = status local namebp = s.namebpt[name] ifnot line then-- 如果没有指定行号 line = 0-- 用一个特殊值0来表示第一个有效行 end -- 是否已经添加了相同的断点 if namebp and namebp[line] then return namebp[line] end
localfunctionremovebreakpoint(id) local s = status if s.bptable[id] == nilthen return end local func = s.bptable[id].func local name = s.bptable[id].name local line = s.bptable[id].line
local dstbp = nil if func then dstbp = s.funcbpt[func] else dstbp = s.namebpt[name] end if dstbp and dstbp[line] then dstbp.num = dstbp.num - 1 dstbp[line] = nil if dstbp.num == 0then dstbp = nil end end
s.bptable[id] = nil s.bpnum = s.bpnum - 1 if s.bpnum == 0then debug.sethook() -- 移除钩子 end end
localfunctiongetfuncinfo(func) local s = status local info = s.funcinfos[func] ifnot info then info = debug.getinfo(func, "SL") if (info.activelines) then info.sortedlines = {} for k, _ inpairs(info.activelines) do table.insert(info.sortedlines, k) end table.sort(info.sortedlines) end s.funcinfos[func] = info end return info end
localfunctionhook(event, line) local s = status if event == "call"or event == "tail call"then local stackinfo = debug.getinfo(2, "nf") local func = stackinfo.func local name = stackinfo.name local funcinfo = getfuncinfo(func) local hasbreak = false if s.funcbpt[func] then hasbreak = true end ifnot hasbreak and s.namebpt[name] then localmin = funcinfo.linedefined localmax = funcinfo.lastlinedefined for k, _ inpairs(s.namebpt[name]) do if k ~= "num"and ((k >= minand k <= max) or k == 0) then hasbreak = true break end end end if event == "call"then-- for tail call, just overwrite s.stackdepth = s.stackdepth + 1 end s.stackinfos[s.stackdepth] = {stackinfo = stackinfo, funcinfo = funcinfo, hasbreak = hasbreak} -- found breakpoint in current function if hasbreak then debug.sethook(hook, "crl") -- add "line" event else-- no breakpoints found debug.sethook(hook, "cr") -- remove "line" event temporarily end elseif event == "return"or event == "tail return"then -- 省略 end
line事件也需要做相应的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
localfunctionhook(event, line) -- 省略 elseif event == "line"then local sinfo = s.stackinfos[s.stackdepth].stackinfo local finfo = s.stackinfos[s.stackdepth].funcinfo local func = sinfo.func local name = sinfo.name local funcbp = s.funcbpt[func] local namebp = s.namebpt[name] if (funcbp and funcbp[line]) or (namebp and namebp[line]) or (namebp and namebp[0] and line == finfo.sortedlines[1]) then local prompt = string.format("%s (%s)%s %s:%d\n", finfo.what, sinfo.namewhat, name, finfo.short_src, line) io.write(prompt) debug.debug() end end end