记一次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 ...
 
随机推荐
- Linux 编译工具 gcc/g++、Make/Makefile、CMake/CMakeLists.txt、qmake
			
前言 编译器的主要工作流程: 源码(Source Code)>> 预处理器(Preprocessor)>> 编译器(Compiler)>> 汇编程序(Assembl ...
 - Linux-Bash终端快捷键
			
^C 终正在运行的进程或放弃当前编辑的命令^U 将光标所在字符到行首之间的所有字符删除,可以使用^E到行尾再^U来删除整行内容^Z 将前台运行的进程放入背景并暂停^D 发送EOF,结束当前输入流,如果 ...
 - IT兄弟连 Java语法教程 数组 多维数组 二维数组的声明
			
Java语言里提供了支持多维数组的语法.但是这里还想说,从数组底层的运行机制上来看是没有多维数组的. Java语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存,数组元 ...
 - 记录使用echarts的graph类型绘制流程图全过程(二)- 多层关系和圆形图片的设置
			
本文主要记录在使用echarts的graph类型绘制流程图时候遇到的2个问题:对于圆形图片的剪切和多层关系的设置 图片的设置 如果用echarts默认的symbol参数来显示图片,会显示图片的原始状态 ...
 - 【Oracle命令】sql语句之排序(order by)
			
通过对数据库数据进行降序排序来达到显示最新数据在前面的效果 -- 降序排序(最新的显示在前面) SELECT * FROM 表名 t ORDER BY t.uploadDatetime DESC; 格 ...
 - 关于unittest单元测试框架中常用的几种用例加载方法
			
unittest模块是Python自带的一个单元测试模块,我们可以用来做单元测试.unittest模块包含了如下几个子模块: 测试用例:TestCase 测试集:TestSuite 加载用例:Test ...
 - 【MySQL】MySQL 8.0的SYS视图
			
MySQL的SYS视图 MySQL8.0的发展越来越趋同与Oracle,为了更好的监控MySQL的一些相关指标,出现了SYS视图,用于监控. 1.MySQL版本 (root@localhost) [s ...
 - apt-get failed:The following signatures were invalid: BADSIG
			
参考如下链接: https://askubuntu.com/questions/131601/gpg-error-release-the-following-signatures-were-inval ...
 - clientHeight—scrollHeight—offsetHeight三者的区别
			
clientHeight,scrollHeight,offsetHeight 这三个dom属性有时让人觉得相似但又不相似 以前对它们的理解也有一些模糊,现在总结一下,方便以后复习 clientHeig ...
 - 转 googlenet论文解读
			
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u014061630/article/det ...