记一次Lua语言中死循环查错
前言
如果在Lua语言中某一处死循环了!你特么的怎么去查出这特么的该死的循环到底在特么的哪里!!!

重现步骤
一打开技能界面,整个游戏就卡死不动了
开始排查
查看一下cpu占用率,unity占用60%+,应该是死循环

一开始采取冒烟式查错法,去一些可疑的地方一个个打断点(我们有lua调试工具可断点)。
游戏的大循环,事件派发基层接口,lua调用c#的基层接口等等,都加了很多断点
可喜的是~~ 完全没有进来!

要怎么才知道当前运行哪段代码呢?这个问题让我想起一个东西
debug.sethook
debug库提供了一种hook的方式,可以通过注册一个handler函数,在lua脚本运行到某个调用时,会触发这个handler,
获取到相应的执行信息,并且给你一个记录和数据维护的机会。
它主要有四种事件会触发这个handler的调用:
- 当调用一个lua函数的时候,会触发call事件
- 当函数返回的时候,会触发一个return事件
- 当执行下一行代码的时候,会触发一个line事件
- 当运行指定数目的指令后,会触发count事件
我们可以通过debug.sethook这个函数来注册一个hook的handler,他有三个参数:
handler的处理函数,hook事件触发后被调用
描述需要hook的事件类型,call、return和line事件分别对应:’c’, ‘r’, ‘l’,可以互相组合成一个字符串
获取count事件的频率(可选)
根据这个函数,我可以让lua每执行一行代码,就把它的文件名已经行号输出到我的日志文件中
debug.sethook(
function (event, line)
WriteLogToFile(debug.getinfo(2).short_src .. ":" .. line)
end
, "l")
写好这个工具后,我来到了技能界面前,开启了hook!然后打开技能界面!出现吧!死循环!
我发现我的日志文件,正在以肉眼可见的速度快速增大!
打开日志后查看后,很快就找到了一段死循环逻辑!
果然,这个害我加班的BUG, 就是我的写的!
总结
debug.sethook确实可以干很多事情,比如基于这个写一个性能监听工具,在函数call、return事件触发时,计算出这个函数的执行时间。
另外这个锅其实是我们把游戏从c#语言转换到lua语言出现的。因为语法不一样,c#那边用整形除以整形得到的还是整形,但是lua会得到浮点数。
记一次Lua语言中死循环查错的更多相关文章
- 理解lua 语言中的点、冒号与self
转载自: http://blog.csdn.net/wangbin_jxust/article/details/12170233 lua编程中,经常遇到函数的定义和调用,有时候用点号调用,有时候用冒号 ...
- Lua语言中的__index,__newindex,rawget和rawset
转自:http://blog.csdn.net/wangbin_jxust/article/details/12108189 在谈及Lua中的__index,__newindex,rawget和raw ...
- lua语言中的假
[1]测试及结论 (1)代码 local var_false = false local var_nil = nil if var_zero then print('var_zero : true') ...
- lua语言三目运算符
[1]lua语言中完整的三目运算符 完整三目运算符形式:(a and {b} or {c})[1] [2]分析原因 大部分C或C++程序员经常会用到三目运算符(三元运算符),形如 a ? b : c; ...
- Lua语言基本语法~运算符
Lua 变量 变量在使用前,必须在代码中进行声明,即创建该变量. 编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量的值. Lua 变量有三种类型:全局变量.局部变量.表中的域. ...
- Lua语言入门
(摘自Lua程序设计) Lua语言中的标识符(或名称)是由任意字母丶数字和下划线组成的字符串(注意不能以数字开头) 下划线加大写字母组成的标识符通常被Lua语言用作特殊用途,应避免将其用作其他用途. ...
- 三种语言(c++、as、lua)中函数的差异性
对于不同的语言, 尤其是静态语言和动态语言, 对于函数的定义(即如何看待一个函数)和处理截然不同.具体来说可以分为两类: 1.将函数视为第一类型值, 即函数和其他的对象一样, 都是语言中一个普通的对象 ...
- C语言中调用Lua
C语言和Lua天生有两大隔阂: 一.C语言是静态数据类型,Lua是动态数据类型 二.C语言需要程序员管理内存,Lua自动管理内存 为了跨越世俗走到一起,肯定需要解决方案. 解决第一点看上去比较容易,C ...
- 在JAVA中使用LUA脚本记,javaj调用lua脚本的函数(转)
最近在做一些奇怪的东西,需要Java应用能够接受用户提交的脚本并执行,网络部分我选择了NanoHTTPD提供基本的HTTP服务器支持,并在Java能承载的许多脚本语言中选择了很久,比如Rhino,Jy ...
随机推荐
- golang之引用自己定义的包
初始目录如下: 其中main.go只有一个主函数main(),用于运行程序,array文件夹是自己定义的包,里面spArr.go位于package array. spArr中的函数名或变量首字母得大写 ...
- python做中学(四)main函数的用法
什么场景下会有main函数? 当该python脚本被作为模块(module)引入(import)时,其中的main()函数将不会被执行. main函数的作用? __name__ == '__main_ ...
- WPF 使用SetParent嵌套窗口
有点类似与Winform的MDI窗口. 使用函数为SetParent和MoveWindow(经常配合). [DllImport("user32.dll", SetLastError ...
- SpringBoot(16)—@ConditionalOnBean与@ConditionalOnClass
@ConditionalOnBean与@ConditionalOnClass 上一篇讲的@Conditional可以通过条件控制是否注入Bean,这篇讲下有关Bean其它几个常用的注解使用方式 @Co ...
- bootstrap table使用colResizable后表格不能自适应
窗口缩小放大后,b表格不能自适应,table加了宽度没效果,求教
- go-控制语句
if else else不能换行 if后最好不加小括号,当然可以加,但建议不加 求平方根 引入math包 调用math.Sqrt(num)函数 switch分支 不用加break来跳出,每一个case ...
- 对Python中函数参数类型及排序问题,三个方面的总结
Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关键字参 ...
- Java基础--常用API--IO流相关API
一.IO流 1.定义: IO流指的是Input/Output流,即输入流/输出流. 输入流:将外界信息写入程序,即从外界获取信息,属于读操作. 输出流:将程序数据发送给外界,即向外界传输数据,属于写操 ...
- UISlider增加触动区域
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value { rect.origin. ...
- ucoreOS_lab8 实验报告
所有的实验报告将会在 Github 同步更新,更多内容请移步至Github:https://github.com/AngelKitty/review_the_national_post-graduat ...