2019年2月15日 星期五

Minecraft Crash Debug: Tried to read NBT tag that was too big; tried to allocate: 2097154bytes where max allowed: 2097152

有一次朋友發現他無法登入 Minecraft Server,並跳出這樣的訊息
由於是登入後斷線,所以沒有 Crash Report 可以調查


初步推斷可能跟資料同步有關,但不曉得是什麼東西(某個方塊、實體?)的資料

打開 latest.log 取得詳細的 Stack Trace
在第 56 行可以發現是在 SPacketChunkData 處理時炸掉的
io.netty.handler.codec.DecoderException: java.lang.RuntimeException: Tried to read NBT tag that was too big; tried to allocate: 2097154bytes where max allowed: 2097152
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:442) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:280) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:396) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:248) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:287) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:624) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:559) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:476) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:438) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858) [netty-all-4.1.9.Final.jar:4.1.9.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_191]
Caused by: java.lang.RuntimeException: Tried to read NBT tag that was too big; tried to allocate: 2097154bytes where max allowed: 2097152
at net.minecraft.nbt.NBTSizeTracker.func_152450_a(NBTSizeTracker.java:25) ~[gh.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:57) ~[fy.class:?]
at net.minecraft.nbt.NBTTagList.func_152446_a(NBTTagList.java:63) ~[ge.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152449_a(NBTTagCompound.java:496) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:58) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152449_a(NBTTagCompound.java:496) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:58) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152449_a(NBTTagCompound.java:496) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:58) ~[fy.class:?]
at net.minecraft.nbt.NBTTagList.func_152446_a(NBTTagList.java:63) ~[ge.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152449_a(NBTTagCompound.java:496) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:58) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152449_a(NBTTagCompound.java:496) ~[fy.class:?]
at net.minecraft.nbt.NBTTagCompound.func_152446_a(NBTTagCompound.java:58) ~[fy.class:?]
at net.minecraft.nbt.CompressedStreamTools.func_152455_a(CompressedStreamTools.java:133) ~[gi.class:?]
at net.minecraft.nbt.CompressedStreamTools.func_152456_a(CompressedStreamTools.java:88) ~[gi.class:?]
at net.minecraft.network.PacketBuffer.func_150793_b(PacketBuffer.java:315) ~[gy.class:?]
at net.minecraft.network.play.server.SPacketChunkData.func_148837_a(SPacketChunkData.java:79) ~[je.class:?]
at net.minecraft.network.NettyPacketDecoder.decode(SourceFile:40) ~[gz.class:?]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:411) ~[netty-all-4.1.9.Final.jar:4.1.9.Final]
... 35 more
view raw latest.log hosted with ❤ by GitHub

由於沒有更詳細的資料,看來需要在 SPacketChunkData 的 Code 加入一些 Debug Log 來取得更多資訊

首先先 Clone MinecraftForge 的 source code:https://github.com/MinecraftForge/MinecraftForge
接著確認目前使用的 Forge 版本:1.12.2-14.23.5.2768

接著要用 Git 切換到目前版本,要先找出 commit hash,這部分可以用 ChangeLog 來確認


切換到目前使用的版本後,執行 gradlew.bat setup
完成後應該會有 projects 的資料夾,裡面應該會有 Clean 和 Forge 資料夾

接著前往 projects\Forge\src\main\java\net\minecraft\network\play\server\SPacketChunkData.java 加上需要的 Debug Log (註:請修改 Forge 資料夾底下的檔案,而不是 Clean 的)
由於是 load 某個 TileEntity 發生錯誤,所以加上 try catch 去攔截,印出目前資料幫助找出出錯的方塊位置
try {
this.tileEntityTags.add(buf.readCompoundTag());
}
catch (Exception e) {
net.minecraftforge.fml.common.FMLLog.log.error("X: " + chunkX + ", Z: " + chunkZ + "k: " + k);
net.minecraftforge.fml.common.FMLLog.log.error("X: " + this.tileEntityTags.get(k - 1).toString());
throw e;
}

接著在專案根目錄下新增 gradle.properties,裡面填上:buildNumber=2768
這樣產出的 Forge 的版本號才會正確,確保通過相依性檢查
執行 gradlew.bat ciWriteBuildNumber 更新 Build Number (他會修改 src/main/java/net/minecraftforge/common/ForgeVersion.java )

修改 Build Number 後,可以開始產出 Forge 的安裝檔,依序執行下列指令:
gradlew.bat genPatches
gradlew.bat build
(註:不要使用 gradlew.bat genPatches build,剛剛修改的 Code 似乎會被改回去)

完成後,在 build\distributions 底下會有 Forge 安裝檔,安裝完成後,去觸發剛剛的 Error
然後在打開 latest.log


使用 NBT 編輯器調查:



發現是 Forestry 的 alveary 導致
後來在單人模式下把裡面的物品全部取出就可以了

(備註:記得裝回原本的 Forge)

參考資料:
https://github.com/MinecraftForge/MinecraftForge/wiki/If-you-want-to-contribute-to-Forge
https://github.com/ForestryMC/ForestryMC/issues/2167
https://github.com/ForestryMC/ForestryMC/issues/1981

沒有留言:

張貼留言