一个简单的例子:
coroutine.resume(coroutine.create(function()
print(debug.traceback())
end))
print(debug.traceback())
输出:
stack traceback:
./v.lua:2: in function <./v.lua:1>
stack traceback:
./v.lua:4: in main chunk
[C]: in ?
这表明协程中的traceback
不知道它是如何恢复的,所以xxx: in main chunk
不会显示。
如何在协同游戏中获得完整的堆叠游戏?
好吧,我在这里找到了一个解决方法。
由于一个Lua虚拟机一次只有一个执行点(这就是为什么那里有一个完整的调用堆栈(,我们可以手动记录恢复信息。
在lua中,手动构建一个恢复堆栈跟踪。
local xresume = coroutine.resume
local xtrace = debug.traceback
-- magic here! Take care of main thread.
local mainthr = coroutine.running() -- captureing is a must.
debug.traceback = function(athr)
if athr then return xtrace(athr) end -- no interest in specified thread.
return xtrace(mainthr)
end
coroutine.resume = function(thr, ...)
-- another magic.
local uptrace = debug.traceback
debug.traceback = function(athr)
if athr then return xtrace(athr) end -- no interest in specified thread.
return xtrace(thr) -- trace the stack of thr.
.. 'n' .. uptrace() -- trace from thr's resume point.
end
local result = { xresume(thr, ...) }
debug.traceback = uptrace
return table.unpack(result)
end
其他提示:
使用全局表存储线程也可以。但您仍然需要捕获主线程,以便可以在任何地方跟踪它。
在C函数中编写代码可以防止回溯到挂接的
coroutine.resume
和debug.traceback
本身,从而提供更清晰的输出。如果不调用
debug.traceback
,则不会对性能造成太大影响。