Call it at any point, and it will give you the name of each function on the stack (up to maxdepth), and arguments and first maxwidth local variables of that function, and if any of the values of the locals are tables, then it will try to shallow print + count them up to maxtablelements numbers. It will also just print any args after the first 3.
Known bug: I cant get the names or locals of functions like widget:UnitCreated(), only 1 call into that. EDIT: FIXED!
All together its almost as good as having a breakpoint!
So the output of it from one specific Chili call (in Chotify:Post()) for those interested, looks like this:
Code: Select all
1: Post @libs/chotify/chotify/chotify.lua:51 Locals:(self=??; obj={title:User is now online, body:<userdata>, }[#2])
2: OnAddUser @LuaMenu/widgets/chobby/components/friend_list_window.lua:75 Locals:(self=??; userName=vbs; userInfo={userName:vbs, accountID:76, lobbyID:skylobby, country:DE, isIgnored:false, }[#7]; userControl=<userdata>)
3: listener @LuaMenu/widgets/chobby/components/friend_list_window.lua:65 Locals:(listener=<function>)
4: ??
5: xpcall @=[C]:-1 Locals:((*temporary)=<function>)
6: _CallListeners @libs/liblobby/lobby/observable.lua:33 Locals:(self=??; event=OnAddUser; eventListeners={1:<function>, 2:<function>, 3:<function>, 4:<function>, 5:<function>, }[#5]; args={1:vbs, 2:<table>, }[#2]; n=2; (for index)=5; (for limit)=5; (for step)=1; i=5; listener=<function>)
7: method @libs/liblobby/lobby/lobby.lua:542 Locals:(self=??; userName=vbs; status={accountID:76, lobbyID:skylobby, country:DE, }[#3]; userInfo={userName:vbs, accountID:76, lobbyID:skylobby, country:DE, isIgnored:false, }[#7])
8: super @sourcetoolong:152 Locals:(self=??; f=_OnAddUser; superClass={RecoverAccount:<function>, Channels:<function>, _OnRegistrationAccepted:<function>, _OnMOTD:<function>, __tostring:<function>, }[#228]; super={GetUserPartyID:<function>, _OnRegistrationAccepted:<function>, __tostring:<function>, _OnFriend:<function>, _OnSuggestedEngineVersion:<function>, }[#230]; s={RecoverAccount:<function>, ForceSpectatorMode:<function>, _OnMOTD:<function>, EnableAllUnits:<function>, _OnLeftTeam:<function>, }[#291]; method=<function>; (*temporary)={}[#0])
9: commandFunction @libs/liblobby/lobby/interface.lua:528 Locals:(self=??; userName=vbs; country=DE; accountID=76; lobbyID=skylobby; userTable={accountID:76, lobbyID:skylobby, country:DE, }[#3])
10: _OnCommandReceived @libs/liblobby/lobby/interface_shared.lua:169 Locals:(self=??; cmdName=ADDUSER; arguments=vbs DE 76 skylobby; cmdId=nil; commandFunction=<function>; pattern=(%S+)%s+(%S%S)%s+(%S+)%s*(.*); fullCmd=ADDUSER vbs DE 76 skylobby; pattern=(%S+)%s+(%S%S)%s+(%S+)%s*(.*); funArgs={1:vbs, 2:DE, 3:76, 4:skylobby, }[#4])
11: CommandReceived @libs/liblobby/lobby/interface_shared.lua:112 Locals:(self=??; command=ADDUSER vbs DE 76 skylobby; cmdId=nil; cmdName=ADDUSER; arguments=vbs DE 76 skylobby; argumentsPos=8)
12: _SocketUpdate @libs/liblobby/lobby/interface_shared.lua:208 Locals:(self=??; readable={1:tcp{client}: 000002c6fd9e6048, tcp{client}: 000002c6fd9e6048:1, }[#2]; writeable={1:tcp{client}: 000002c6fd9e6048, tcp{client}: 000002c6fd9e6048:1, }[#2]; err=nil; host=176.56.236.106; port=8200; brec=9543; bsent=204; age=0; (for generator)=<function>)
13: SafeUpdate @libs/liblobby/lobby/interface_shared.lua:261 Locals:(self=??)
14: ??
15: xpcall @=[C]:-1 Locals:((*temporary)=<function>)
Code: Select all
local function traceFullEcho(maxdepth, maxwidth, maxtableelements, ...)
-- Some docs are in order:
--
local tracedebug = false
functionsource= true
maxdepth = maxdepth or 16
maxwidth = maxwidth or 10
maxtableelements = maxtableelements or 6 -- max amount of elements to expand from table type values
local function dbgt(t, maxtableelements)
local count = 0
local res = ''
for k,v in pairs(t) do
count = count + 1
if count < maxtableelements then
if tracedebug then Spring.Echo(count, k) end
if type(k) == "number" and type(v) == "function" then -- try to get function lists?
if tracedebug then Spring.Echo(k,v, debug.getinfo(v), debug.getinfo(v).name) end --debug.getinfo(v).short_src)?
res = res .. tostring(k) .. ':' .. ((debug.getinfo(v) and debug.getinfo(v).name) or "<function>") ..', '
else
res = res .. tostring(k) .. ':' .. tostring(v) ..', '
end
end
end
res = '{'..res .. '}[#'..count..']'
return res
end
local myargs = {...}
infostr = ""
for i,v in ipairs(myargs) do
infostr = infostr .. tostring(v) .. "\t"
end
if infostr ~= "" then infostr = "Trace:[" .. infostr .. "]\n" end
local functionstr = "" -- "Trace:["
for i = 2, maxdepth do
if debug.getinfo(i) then
local funcName = (debug and debug.getinfo(i) and debug.getinfo(i).name)
if funcName then
functionstr = functionstr .. tostring(i-1) .. ": " .. tostring(funcName) .. " "
local arguments = ""
local funcName = (debug and debug.getinfo(i) and debug.getinfo(i).name) or "??"
if funcName ~= "??" then
if functionsource and debug.getinfo(i).source then
local source = debug.getinfo(i).source
if string.len(source) > 128 then source = "sourcetoolong" end
functionstr = functionstr .. " @" .. source
end
if functionsource and debug.getinfo(i).linedefined then
functionstr = functionstr .. ":" .. tostring(debug.getinfo(i).linedefined)
end
for j = 1, maxwidth do
local name, value = debug.getlocal(i, j)
if not name then break end
if tracedebug then Spring.Echo(i,j, funcName,name) end
local sep = ((arguments == "") and "") or "; "
if tostring(name) == 'self' then
arguments = arguments .. sep .. ((name and tostring(name)) or "name?") .. "=" .. tostring("??")
else
local newvalue
if maxtableelements > 0 and type({}) == type(value) then newvalue = dbgt(value, maxtableelements) else newvalue = value end
arguments = arguments .. sep .. ((name and tostring(name)) or "name?") .. "=" .. tostring(newvalue)
end
end
end
functionstr = functionstr .. " Locals:(" .. arguments .. ")" .. "\n"
else
functionstr = functionstr .. tostring(i-1) .. ": ??\n"
end
else break end
end
Spring.Echo(infostr .. functionstr)
end