CC: Tweaked

CC: Tweaked

42M Downloads

CME in SPackerChunkData related to Advanced Monitor

LemADEC opened this issue ยท 1 comments

commented

As of 1.12.2-1.83.1, a server side CME crash is observed when moving a WarpDrive ship with Advanced monitors across chunk border.
This is seen on this modpack version: https://minecraft.curseforge.com/projects/spacearchitect/files/2720587

[21:03:57] [Server thread/ERROR] [net.minecraft.server.MinecraftServer]: Encountered an unexpected exception
net.minecraft.util.ReportedException: Exception ticking world
	at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:762) ~[MinecraftServer.class:?]
	at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:397) ~[nz.class:?]
	at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:668) ~[MinecraftServer.class:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526) [MinecraftServer.class:?]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
Caused by: java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445) ~[?:1.8.0_212]
	at java.util.HashMap$EntryIterator.next(HashMap.java:1479) ~[?:1.8.0_212]
	at java.util.HashMap$EntryIterator.next(HashMap.java:1477) ~[?:1.8.0_212]
	at net.minecraft.network.play.server.SPacketChunkData.<init>(SourceFile:43) ~[je.class:?]
	at net.minecraft.server.management.PlayerChunkMapEntry.func_187280_d(PlayerChunkMapEntry.java:255) ~[ot.class:?]
	at net.minecraft.server.management.PlayerChunkMap.func_72693_b(SourceFile:115) ~[ou.class:?]
	at net.minecraft.world.WorldServer.func_72835_b(WorldServer.java:227) ~[oo.class:?]
	at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:756) ~[MinecraftServer.class:?]
	... 4 more

Issue was found initially in SMP, with SpongeForge-1.12.2-2825-7.1.6-RC3765. The latest didn't report multi-threaded modification/loading of the world, so I'm assuming it's not a multi-threading issue per say, more a modification of the collection within a loop.
Issue is also reproduced without SpongeForge, in single player.

Replacing 2 specific Advanced monitors with a dummy block (glass), doesn't reproduce the issue. Restoring those 2 peripherals does reproduce the issue.
Removing 1 specific Advanced computer doesn't reproduce the issue. Restoring the computer (without the LAN wiring), does reproduce the issue.
Note: that computer is inactive (left 'as is' after loading/placing it, didn't try to open it).
Here's a view of the Advanced computer and its 2 Advanced monitor in question:
image

Crash report after removing a lot of mods: https://gist.github.com/LemADEC/2a319aba401838080bbf471cfba1681e

I did some digging in Forge source code and noted the following:
CME happens in the SPacketChunkData constructor. The latest is looping through the TileEntities in the given chunk, if they are in the range of updates, it'll call TileEntity.getUpdateTag():

    public SPacketChunkData(Chunk chunkIn, int changedSectionFilter)
    {
        this.chunkX = chunkIn.x;
        this.chunkZ = chunkIn.z;
        this.fullChunk = changedSectionFilter == 65535;
        boolean flag = chunkIn.getWorld().provider.hasSkyLight();
        this.buffer = new byte[this.calculateChunkSize(chunkIn, flag, changedSectionFilter)];
        this.availableSections = this.extractChunkData(new PacketBuffer(this.getWriteBuffer()), chunkIn, flag, changedSectionFilter);
        this.tileEntityTags = Lists.<NBTTagCompound>newArrayList();

        for (Entry<BlockPos, TileEntity> entry : chunkIn.getTileEntityMap().entrySet())
        {
            BlockPos blockpos = entry.getKey();
            TileEntity tileentity = entry.getValue();
            int i = blockpos.getY() >> 4;

            if (this.isFullChunk() || (changedSectionFilter & 1 << i) != 0)
            {
                NBTTagCompound nbttagcompound = tileentity.getUpdateTag();
                this.tileEntityTags.add(nbttagcompound);
            }
        }
    }

As such, the CME crash happens if the TileEntity map was changed during the loop in that specific chunk.
From a quick check in the Chunk and World objects, I've listed the following possible trigger that would modify the map and cause the CME:
1- a tile entity in that chunk was removed
2- a tile entity was retrieved but happens to be invalid (see Chunk.getTileEntity())
3- a tile entity was added

Any thought on what could cause this CME?

commented
[20:43:40] [Server thread/ERROR] [computercraft]: Putting BlockPos{x=-38561, y=227, z=29695} (dan200.computercraft.shared.peripheral.monitor.TileMonitor)
java.lang.RuntimeException: !
	at dan200.computercraft.shared.proxy.ComputerCraftProxyCommon$LoggingHashMap.put(ComputerCraftProxyCommon.java:220) [ComputerCraftProxyCommon$LoggingHashMap.class:?]
	at net.minecraft.world.chunk.Chunk.func_177426_a(Chunk.java:836) [axw.class:?]
	at net.minecraft.world.World.func_175690_a(World.java:2457) [amu.class:?]
	at net.minecraft.world.chunk.Chunk.func_177424_a(Chunk.java:801) [axw.class:?]
	at net.minecraft.world.World.func_175625_s(World.java:2399) [amu.class:?]
	at dan200.computercraft.shared.common.BlockGeneric.onNeighborChange(BlockGeneric.java:63) [BlockGeneric.class:?]
	at net.minecraft.world.World.func_175666_e(World.java:3812) [amu.class:?]
	at net.minecraft.tileentity.TileEntity.func_70296_d(TileEntity.java:163) [avj.class:?]
	at dan200.computercraft.shared.common.TileGeneric.updateBlock(TileGeneric.java:44) [TileGeneric.class:?]
	at dan200.computercraft.shared.computer.blocks.TileComputerBase.createServerComputer(TileComputerBase.java:422) [TileComputerBase.class:?]
	at dan200.computercraft.shared.computer.blocks.TileComputerBase.writeDescription(TileComputerBase.java:456) [TileComputerBase.class:?]
	at dan200.computercraft.shared.computer.blocks.TileComputer.writeDescription(TileComputer.java:71) [TileComputer.class:?]
	at dan200.computercraft.shared.common.TileGeneric.func_189517_E_(TileGeneric.java:148) [TileGeneric.class:?]
	at net.minecraft.network.play.server.SPacketChunkData.<init>(SourceFile:52) [je.class:?]
	at net.minecraft.server.management.PlayerChunkMapEntry.func_187272_b(PlayerChunkMapEntry.java:157) [ot.class:?]
	at net.minecraft.server.management.PlayerChunkMap.func_72693_b(SourceFile:165) [ou.class:?]
	at net.minecraft.world.WorldServer.func_72835_b(WorldServer.java:227) [oo.class:?]
	at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:756) [MinecraftServer.class:?]
	at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:668) [MinecraftServer.class:?]
	at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:185) [chd.class:?]
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526) [MinecraftServer.class:?]
	at java.lang.Thread.run(Unknown Source) [?:1.8.0_201]

Well, looks like an entirely different tile entity is to blame! Still my fault though.