来看懂游戏《Minecraft》的崩溃报告吧!服务端客户端
如何看懂Minecraft报错的关键信息。
让你如何看懂Minecraft报错
前⾔
[WARNING] 本篇适⽤于Minecraft服务端/客户端报错的诊断分析,其他游戏除外,⽐如⽹易
[WARNING] 本篇适⽤于Minecraft服务端/客户端报错的诊断分析,其他游戏除外,⽐如⽹易
[WARNING] 本篇适⽤于Minecraft服务端/客户端报错的诊断分析,其他游戏除外,⽐如⽹易
我所说的报错,指的是⼀款名为《Minecraft》的游戏中的报错。并不是《我的世界》的报错
在⼤家游玩Minecraft时,有时需要装⼀些Forge模组以此来提⾼可玩度,但⾃⼰配置模组包的时候,总会造成游戏崩溃,并且⼤多数⼈还看不懂崩溃报告更有甚者连崩溃报告输出⽬录都不知道在哪,于是本篇教程应运⽽⽣。
⼀些俏⽪话
Minecraft这个游戏,各种BUG和解决⽅案如果写成⼀堆不重复的书,摞起来的厚度可以⽐姚明还⾼。
所以这个游戏不是⼀般的神奇,尤其是当你在看崩溃报告的时,你更会体验到这⼀点。
你不加模组,MC也会崩溃,加了还是崩溃。这是⼀个⽐较罕见的情况。
⼤多数情况是你⼀股脑加了⼀堆模组,然后突然蹦了,就不知道怎么办了。
幸运的是,这时候,你有60%的概率可以到问题所在并解决这个问题。
寻崩溃⽇志
⾸先,你得知道你的客户端/服务端⽬录
客户端的CrashReport⽂件夹⽬录:(.minecraft\crash-reports)
如果你启⽤了版本隔离,那就在(.minecraft\versions\xxxx\crash-reports)
服务端的CrashReport在你的服务端根⽬录下。
这个条件的前提是你的服务端是⼈类已知的服务端,⽽不是外星⼈制造的服务端。
打开崩溃⽇志
接下来我们对报错的分析,均以⼀个Minecraft 1.12.2 Forge服务端为例
嗯,我们可以看到,crashreport⽬录下的所有⽂件都是以
crash-⽇期_具体时间-命名的
如果是客户端的崩溃报告⽇志,后⾯的server则是client。
然后我们到⼀个最新的⽇志打开并分析。
告诉你怎么瞬间到最新崩溃⽇志,
直接点击这个按钮就完事了。然后会按照报告的⽣成时间进⾏排列。
重要的事说三遍
接下来我们对报错的分析,均以⼀个Minecraft 1.12.2 Forge服务端为例
接下来我们对报错的分析,均以⼀个Minecraft 1.12.2 Forge服务端为例
接下来我们对报错的分析,均以⼀个Minecraft 1.12.2 Forge服务端为例
下载⽂本编辑器
⾸先你需要⼀个⽂本编辑器来查看崩溃报告,
这⾥我推荐微软官⽅的Visaul Code: .
然后我们就可以愉快地打开报告进⾏查看了。
开始分析
好了,我们说了这么多废话,是时候开始正式的分析了。
我估计前⾯的事⼤多数⼈已经做完了,就等着我讲这个。
废话不多说,开始。
打开后我们⾸先看到的是这个
其中,WARNING coremods are present:xxxxx 是废话,你根本不⽤管。
产⽣这种警告是因为有的作者动了Minecraft底层的代码,然后Forge为了⽅便,给你整出来了。
在99.9999999%的情况下,coremods在理论上不会造成崩溃。所以你可以忽略这些。
再往下看。
我们先引出⼏个重要概念,当然你不⽤理解。
你会发现这些报错⾥都会有⼀⼤堆的⽂字:
xx
at
这些有专门的术语,叫做栈帧(stacktrace)。
平时我们运⾏Minecraft等java应⽤程序,是在JVM上运⾏的。
JVM⾥内存被划分为五⼤块,分别是:
1. CPU寄存器;
2. 本地⽅法栈;
3. ⽅法区;
4. 栈内存;
5. 堆内存。
寄存器部分容量不够存放太多数据,所以运⾏中的代码⽅法会存放在内存中⼀个叫栈内存内,你可以理解为⼀个⽅法⼀个栈帧。假设报错有20个 ,那就意味着有20个⽅法被调⽤过了。
⽽会出现这么多的栈帧的原因,是因为上⼀个栈帧爆出异常后并没有相应的异常处理器去捕获,就会接着爆,报错栈帧就会形成套娃式增长,所以往往最的栈帧就是最后爆出异常的。越往上,这些⽅法存在问题的可能性也就越⼤。
我们可以看见,顶上有
这3⾏东西,
第⼀⾏是废话,你可以不⽤管。
第⼆⾏这个报告中最后⼀个栈帧抛出异常的时间。
第三⾏是这个报错的描述,也就是⼈类可读的⼤⽩话形式。
从这开始,下⾯的句⼦都不是⼈类可读形式,当然。相⽐原版的报错来说,Forge的报错⾮常⾮常⼈性化了。
我们可以从第三⾏看到,这个崩溃报告的描述是 Ticking player。
player代表球员玩家,也就是说这个报错跟玩家有关系。
Tciking指的是刻,这个以后再说。
然后我们再来看下⾯的报错
这个报错⽚段中。
第⼀⾏是错误类型
我们可以看到,这个报错的错误类型是
java.lang.IndexOutOfBoundsException
如果你开过Minecraft组服务器,或者学过java。你可以知道
这个叫做数组下标越界异常,是⼀个在Minecraft中⾮常常见的异常。
我们不⽤去管这个具体是什么,直接往下看。
下⾯那些⼀⼤堆栈帧的排列,并⾮没有顺序。
这些栈帧的排列⽅式,是由它们抛出异常的顺序决定的。
听不懂?我们看图
红⾊箭头指的栈帧,是第⼀个抛出异常的栈帧。然后黄⾊箭头的栈帧,是最后⼀个抛出异常的栈帧。
现在你懂了栈帧的排列顺序了吧。
最前⾯的栈帧就是最后⼀个抛出错误的位置,也就是说⼤多数情况我们是从这⾥下⼿。
或者从第⼀个栈帧的后⾯⼏个栈帧下⼿。
好,我们继续看。
现在我们遇到的是指数组下标越界异常。
例如:⼀个ArrayList数组中没有元素,⽽你想获取第⼀个元素,运⾏是就会报此类型的错误。
crash是什么意思听不懂?我们看报错!
看看,最后栈帧抛出的异常,就是ArrayList在获取元素的时候没到。
当然你不⽤在意这个,继续往下看。
这⾥已经出现了产⽣这个崩溃的模组名字。
这个模组叫做:slashblade,也就是⼤家经常玩的拔⼑剑。
然后你发现,这些栈帧的形式都是
(xxxx.java:xxxx)
如果你以压缩包形式打开拔⼑剑模组JAR⽂件,
你会发现⼀件事。
那就是这些栈帧其实就是这个JAR压缩包的内部⽬录结构
就⽐如这条栈帧
at mods.flammpfeil.slashblade.item.(ItemSlashBlade.java:310)
我们可以把所有的" . “去掉,改成” / 或者 \ "
这样就是⼀个⽂件⽬录了!!
at mods.flammpfeil.slashblade.item.(ItemSlashBlade.java:310)
相当于
at mods\flammpfeil\slashblade\item\itemSlashBlade
⽽这段蓝⾊的,,指的是这个栈帧中抛出异常的⽅法。并不是⽂件⽬录。
括号⾥的ItemSlashBlade.java:310指的是,
这个异常发⽣在
ItemSlashBlade.java这个⽂件夹中的第310⾏。
是不是突然明⽩⼀⼤堆东西
下⾯的图就是我⽤压缩包形式打开拔⼑剑模组⽂件后,
把栈帧转换成⽬录,就到了抛出异常的⽂件路径。
深度分析
好了,那么我们接下来进⾏硬核(Hardcore)分析吧
上⾯我们已经到了这个崩溃中有拔⼑剑的信息
那么我们就进⼀步分析。
我们知道,拔⼑剑有⼏个栈帧抛出了异常,那么我们以最后⼀个抛出异常的栈帧进⾏分析。
amods.flammpfeil.slashblade.item.
从这段信息中我们得知,这个抛出异常的⽅法在ComboSequence.Get中
ComboSequence翻译过来就是组合技,然后我们进⼀步分析
既然这个崩溃出在了拔⼑剑的组合技上,那也就是说。
我的服务器崩溃是因为,有某个⼈⽤了拔⼑的组合技,然后不知道触发了什么BUG。服务器就因此崩溃了。
很好,如果你能分析到这⼀步,那就快接近真相了!
上代码
我们⾸先登陆Github(世界上最⼤的代码托管站)
然后到拔⼑剑的开源代码仓库,并依次进⼊⽬录
src/main/java/mods/flammpfeil/slashblade/item/ItemSlashBlade.java
然后这个就是抛出异常的原代码了。
然后搜索⽅法
//报错产⽣的位置
public static ComboSequence getComboSequence(NBTTagCompound tag){
(Int(comboSeqStr));
}
很好,你可能看见⼀个熟悉的词汇,叫做NBT
我们引⽤⼀段百度百科上的话
⼆进制命名标签(Name Binary Tag),NBT格式为Minecraft中⽤于向⽂件中存储数据的⼀种存储格式。NBT格式以树形结构并配以许多标签的形式存储数据
既然如此,我们就可以知道
这个报错的产⽣和NBT标签有关系,然后我们只需要看见tag这个词即可。
这就代表,这个异常的产⽣是因为在获取组合技的NBT数据时产⽣异常,在结合最后⼀个抛出的异常
也就是数组下标越界异常
我们就可以推导出这个异常的产⽣了。
⼀个玩家在使⽤拔⼑的组合技时,然后这个组合技因为某种原因⽆法使⽤,也就是ArrayList数组元素为空,导致抛出数组下标越界异常,引发Minecraft服务器保护机制然后⾃动关服。并产⽣这个报错。
以及你会发现栈帧⾥有⼀些例如func_xxxxx_x的奇怪⽅法名。
这些是混淆后的⽅法名,如果要深究报错产⽣的话,我们就必须反混淆以便知道具体是什么⽅法造成了这种问题。
这⾥我推荐使⽤MinecraftMappings这个项⽬
这个项⽬可以在不⽤下载很多Forge的情况下⽅便地⽣成相应的mapping⽂件,⽅便查混淆后的⽅法
名、字段等的具体含义。
这是GitHub的连接,如果你不会⽤git等⼯具的话,只需要按下图操作⾛。
点击Code然后点击Download ZIP
然后你还需要⼀个IDE,最好⽤IntelliJ IDEA的community edition(社区版)
IDEA下载后按引导安装。
不要怕看不懂英⽂和嫌⿇烦,因为你都⾛到这⼀步了,还有什么理由give up呢?
安装完毕后启动IDEA。
然后刚刚把下载完的源码包解压到⼀个⽬录,然后复制源码包解压后的路径并在IDEA⾥导⼊新⼯程(Import Project),路径就粘贴刚刚你复制的源码包解压后路径。然后IDEA会⾃动导⼊这个项⽬,导⼊速度和⽹速有关系,这不需要不管。如果失败那就多试⼏次或者使⽤代理加速。
导⼊完毕后只需要运⾏main.kt,就可以⾃动⽣成mapping⽂件了,在build⽬录下。
分别有method、fields、params这3个csv格式的⽂件。
可以通过wsp或微软office系列软件打开,是表格。
然后直接在⾥⾯搜索报错⾥出现过的对应func、field等字段,就可以看到相关说明了。
有必要还可以下载相关forge源码查询。
好了,我们继续看下⾯的栈帧。
对于下⾯的栈帧来说,上⾯的栈帧全是主要原因。也就是说下⾯的栈帧都是废话
不过我还是贴出来让你了解⼀下。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论