如果Lua语言中某个地方存在无限循环! 你到底要怎么找出这个该死的循环到底在哪里! ! !
重现步骤
一打开技能界面,整个游戏就卡住了。
开始故障排除
检查CPU使用率。 Unity占据了60%+。 它应该是一个无限循环。
一开始我们采用了基于冒烟的错误检查方法unity 死循环协程,去一些可疑的地方一一断点(我们有Lua调试工具可以断点)。
游戏大循环、事件派发基础接口、Lua调用C#基础接口等添加了很多断点。
好消息是~~他根本没有进来!
我怎么知道当前正在运行哪一段代码?这个问题让我想起了一件事
调试.sethook
调试库提供了一个钩子方法。 您可以注册一个处理函数。 当Lua脚本运行到某个调用时,处理程序将被触发。
获取相应的执行信息,让您有机会记录和维护数据。
有四个主要事件将触发此处理程序的调用:
当调用Lua函数时,会触发call事件。 当函数返回时游戏动态,会触发返回事件。 当执行下一行代码时,会触发行事件。 运行指定数量的指令后,将触发计数事件。
我们可以通过 debug.sethook 函数注册一个钩子处理程序,该函数有三个参数:
触发钩子事件后,将调用处理程序的处理函数。
描述需要hook的事件类型。 呼叫、返回和线路事件分别对应于:'c'、'r'、'l'。 它们可以组合成一个字符串。
获取计数事件的频率(可选)
根据这个函数,我可以要求Lua在每次执行一行代码时将其文件名和行号输出到我的日志文件中。
debug.sethook(
function (event, line)
WriteLogToFile(debug.getinfo(2).short_src .. ":" .. line)
end
, "l")
写完这个工具,来到技能界面,勾上! 然后打开技能界面! 出现! 无限循环!
我发现我的日志文件正在以肉眼可见的速度快速增长!
打开日志查看后,很快发现了一段死循环逻辑!
果然,这个导致我加班的bug是我写的!
总结
debug.sethook确实可以做很多事情,比如基于此编写一个性能监控工具材质材料,在函数调用和返回事件触发时计算这个函数的执行时间。
另外,这个问题实际上是在我们将游戏从c#语言转换为lua语言时出现的。 因为语法不同,如果在 C# 中用一个整数除以一个整数,仍然会得到一个整数unity 死循环协程,但 Lua 会得到一个浮点数。
文章来源:https://blog.csdn.net/aefdwu9215/article/details/102276760