aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/1062-Detail-more-information-in-watchdog-dumps.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/1062-Detail-more-information-in-watchdog-dumps.patch')
-rw-r--r--patches/server/1062-Detail-more-information-in-watchdog-dumps.patch295
1 files changed, 295 insertions, 0 deletions
diff --git a/patches/server/1062-Detail-more-information-in-watchdog-dumps.patch b/patches/server/1062-Detail-more-information-in-watchdog-dumps.patch
new file mode 100644
index 0000000000..fafa3413d0
--- /dev/null
+++ b/patches/server/1062-Detail-more-information-in-watchdog-dumps.patch
@@ -0,0 +1,295 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Thu, 26 Mar 2020 21:59:32 -0700
+Subject: [PATCH] Detail more information in watchdog dumps
+
+- Dump position, world, velocity, and uuid for currently ticking entities
+- Dump player name, player uuid, position, and world for packet handling
+
+diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
+index e300293ba64a8ac54cc9c5348ecc9f3ed2d27e19..3c866432c8a938c677a315612f3e159bda67a2a2 100644
+--- a/src/main/java/net/minecraft/network/Connection.java
++++ b/src/main/java/net/minecraft/network/Connection.java
+@@ -632,7 +632,13 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
+ if (!(this.packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginPacketListener)
+ || loginPacketListener.state != net.minecraft.server.network.ServerLoginPacketListenerImpl.State.VERIFYING
+ || Connection.joinAttemptsThisTick++ < MAX_PER_TICK) {
++ // Paper start - detailed watchdog information
++ net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener);
++ try {
+ tickablepacketlistener.tick();
++ } finally {
++ net.minecraft.network.protocol.PacketUtils.packetProcessing.pop();
++ } // Paper end - detailed watchdog information
+ } // Paper end - Buffer joins to world
+ }
+
+diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
+index f7197f1347251a37dd0f6d9ffa2f09bc3a4e1233..1f7f68aad97ee73763c042837f239bdc7167db55 100644
+--- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java
++++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
+@@ -20,6 +20,24 @@ public class PacketUtils {
+
+ private static final Logger LOGGER = LogUtils.getLogger();
+
++ // Paper start - detailed watchdog information
++ public static final java.util.concurrent.ConcurrentLinkedDeque<PacketListener> packetProcessing = new java.util.concurrent.ConcurrentLinkedDeque<>();
++ static final java.util.concurrent.atomic.AtomicLong totalMainThreadPacketsProcessed = new java.util.concurrent.atomic.AtomicLong();
++
++ public static long getTotalProcessedPackets() {
++ return totalMainThreadPacketsProcessed.get();
++ }
++
++ public static java.util.List<PacketListener> getCurrentPacketProcessors() {
++ java.util.List<PacketListener> ret = new java.util.ArrayList<>(4);
++ for (PacketListener listener : packetProcessing) {
++ ret.add(listener);
++ }
++
++ return ret;
++ }
++ // Paper end - detailed watchdog information
++
+ public PacketUtils() {}
+
+ public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, ServerLevel world) throws RunningOnDifferentThreadException {
+@@ -29,6 +47,8 @@ public class PacketUtils {
+ public static <T extends PacketListener> void ensureRunningOnSameThread(Packet<T> packet, T listener, BlockableEventLoop<?> engine) throws RunningOnDifferentThreadException {
+ if (!engine.isSameThread()) {
+ engine.executeIfPossible(() -> {
++ packetProcessing.push(listener); // Paper - detailed watchdog information
++ try { // Paper - detailed watchdog information
+ if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players
+ if (listener.shouldHandleMessage(packet)) {
+ try {
+@@ -47,6 +67,12 @@ public class PacketUtils {
+ } else {
+ PacketUtils.LOGGER.debug("Ignoring packet due to disconnection: {}", packet);
+ }
++ // Paper start - detailed watchdog information
++ } finally {
++ totalMainThreadPacketsProcessed.getAndIncrement();
++ packetProcessing.pop();
++ }
++ // Paper end - detailed watchdog information
+
+ });
+ throw RunningOnDifferentThreadException.RUNNING_ON_DIFFERENT_THREAD;
+diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
+index cf692267c6376ed8484478dc90f4f905d8325618..3295843371d56fa76eb8d7a29efb675721dc6a43 100644
+--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
++++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
+@@ -1254,7 +1254,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+
+ }
+
++ // Paper start - log detailed entity tick information
++ // TODO replace with varhandle
++ static final java.util.concurrent.atomic.AtomicReference<Entity> currentlyTickingEntity = new java.util.concurrent.atomic.AtomicReference<>();
++
++ public static List<Entity> getCurrentlyTickingEntities() {
++ Entity ticking = currentlyTickingEntity.get();
++ List<Entity> ret = java.util.Arrays.asList(ticking == null ? new Entity[0] : new Entity[] { ticking });
++
++ return ret;
++ }
++ // Paper end - log detailed entity tick information
++
+ public void tickNonPassenger(Entity entity) {
++ // Paper start - log detailed entity tick information
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
++ try {
++ if (currentlyTickingEntity.get() == null) {
++ currentlyTickingEntity.lazySet(entity);
++ }
++ // Paper end - log detailed entity tick information
+ // Spigot start
+ /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out EAR 2
+ entity.tickCount++;
+@@ -1284,6 +1303,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
+ this.tickPassenger(entity, entity1, isActive); // Paper - EAR 2
+ }
+
++ // Paper start - log detailed entity tick information
++ } finally {
++ if (currentlyTickingEntity.get() == entity) {
++ currentlyTickingEntity.lazySet(null);
++ }
++ }
++ // Paper end - log detailed entity tick information
+ }
+
+ private void tickPassenger(Entity vehicle, Entity passenger, boolean isActive) { // Paper - EAR 2
+diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
+index 1f54752a4ea0788e73279cd99c7c35e3b5d9b6ce..7ac7d0729705cb02f22277be3c467aed4f69ec0e 100644
+--- a/src/main/java/net/minecraft/world/entity/Entity.java
++++ b/src/main/java/net/minecraft/world/entity/Entity.java
+@@ -1144,8 +1144,43 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ return this.onGround;
+ }
+
++ // Paper start - detailed watchdog information
++ public final Object posLock = new Object(); // Paper - log detailed entity tick information
++
++ private Vec3 moveVector;
++ private double moveStartX;
++ private double moveStartY;
++ private double moveStartZ;
++
++ public final Vec3 getMoveVector() {
++ return this.moveVector;
++ }
++
++ public final double getMoveStartX() {
++ return this.moveStartX;
++ }
++
++ public final double getMoveStartY() {
++ return this.moveStartY;
++ }
++
++ public final double getMoveStartZ() {
++ return this.moveStartZ;
++ }
++ // Paper end - detailed watchdog information
++
+ public void move(MoverType type, Vec3 movement) {
+ final Vec3 originalMovement = movement; // Paper - Expose pre-collision velocity
++ // Paper start - detailed watchdog information
++ ca.spottedleaf.moonrise.common.util.TickThread.ensureTickThread("Cannot move an entity off-main");
++ synchronized (this.posLock) {
++ this.moveStartX = this.getX();
++ this.moveStartY = this.getY();
++ this.moveStartZ = this.getZ();
++ this.moveVector = movement;
++ }
++ try {
++ // Paper end - detailed watchdog information
+ if (this.noPhysics) {
+ this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z);
+ } else {
+@@ -1269,6 +1304,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ gameprofilerfiller.pop();
+ }
+ }
++ // Paper start - detailed watchdog information
++ } finally {
++ synchronized (this.posLock) { // Paper
++ this.moveVector = null;
++ } // Paper
++ }
++ // Paper end - detailed watchdog information
+ }
+
+ private void applyMovementEmissionAndPlaySound(Entity.MovementEmission moveEffect, Vec3 movement, BlockPos landingPos, BlockState landingState) {
+@@ -4910,7 +4952,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ }
+
+ public void setDeltaMovement(Vec3 velocity) {
++ synchronized (this.posLock) { // Paper
+ this.deltaMovement = velocity;
++ } // Paper
+ }
+
+ public void addDeltaMovement(Vec3 velocity) {
+@@ -5016,7 +5060,9 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
+ }
+ // Paper end - Fix MC-4
+ if (this.position.x != x || this.position.y != y || this.position.z != z) {
++ synchronized (this.posLock) { // Paper
+ this.position = new Vec3(x, y, z);
++ } // Paper
+ int i = Mth.floor(x);
+ int j = Mth.floor(y);
+ int k = Mth.floor(z);
+diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
+index c9e17225bc52fe5e7b2dc0908db225a86c6e94d1..f7a4fee9bb25ff256dc2e5ea26bfbceca6a49167 100644
+--- a/src/main/java/org/spigotmc/WatchdogThread.java
++++ b/src/main/java/org/spigotmc/WatchdogThread.java
+@@ -22,6 +22,78 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
+ private volatile long lastTick;
+ private volatile boolean stopping;
+
++ // Paper start - log detailed tick information
++ private void dumpEntity(net.minecraft.world.entity.Entity entity) {
++ Logger log = Bukkit.getServer().getLogger();
++ double posX, posY, posZ;
++ net.minecraft.world.phys.Vec3 mot;
++ double moveStartX, moveStartY, moveStartZ;
++ net.minecraft.world.phys.Vec3 moveVec;
++ synchronized (entity.posLock) {
++ posX = entity.getX();
++ posY = entity.getY();
++ posZ = entity.getZ();
++ mot = entity.getDeltaMovement();
++ moveStartX = entity.getMoveStartX();
++ moveStartY = entity.getMoveStartY();
++ moveStartZ = entity.getMoveStartZ();
++ moveVec = entity.getMoveVector();
++ }
++
++ String entityType = net.minecraft.world.entity.EntityType.getKey(entity.getType()).toString();
++ java.util.UUID entityUUID = entity.getUUID();
++ net.minecraft.world.level.Level world = entity.level();
++
++ log.log(Level.SEVERE, "Ticking entity: " + entityType + ", entity class: " + entity.getClass().getName());
++ log.log(Level.SEVERE, "Entity status: removed: " + entity.isRemoved() + ", valid: " + entity.valid + ", alive: " + entity.isAlive() + ", is passenger: " + entity.isPassenger());
++ log.log(Level.SEVERE, "Entity UUID: " + entityUUID);
++ log.log(Level.SEVERE, "Position: world: '" + (world == null ? "unknown world?" : world.getWorld().getName()) + "' at location (" + posX + ", " + posY + ", " + posZ + ")");
++ log.log(Level.SEVERE, "Velocity: " + (mot == null ? "unknown velocity" : mot.toString()) + " (in blocks per tick)");
++ log.log(Level.SEVERE, "Entity AABB: " + entity.getBoundingBox());
++ if (moveVec != null) {
++ log.log(Level.SEVERE, "Move call information: ");
++ log.log(Level.SEVERE, "Start position: (" + moveStartX + ", " + moveStartY + ", " + moveStartZ + ")");
++ log.log(Level.SEVERE, "Move vector: " + moveVec.toString());
++ }
++ }
++
++ private void dumpTickingInfo() {
++ Logger log = Bukkit.getServer().getLogger();
++
++ // ticking entities
++ for (net.minecraft.world.entity.Entity entity : net.minecraft.server.level.ServerLevel.getCurrentlyTickingEntities()) {
++ this.dumpEntity(entity);
++ net.minecraft.world.entity.Entity vehicle = entity.getVehicle();
++ if (vehicle != null) {
++ log.log(Level.SEVERE, "Detailing vehicle for above entity:");
++ this.dumpEntity(vehicle);
++ }
++ }
++
++ // packet processors
++ for (net.minecraft.network.PacketListener packetListener : net.minecraft.network.protocol.PacketUtils.getCurrentPacketProcessors()) {
++ if (packetListener instanceof net.minecraft.server.network.ServerGamePacketListenerImpl) {
++ net.minecraft.server.level.ServerPlayer player = ((net.minecraft.server.network.ServerGamePacketListenerImpl)packetListener).player;
++ long totalPackets = net.minecraft.network.protocol.PacketUtils.getTotalProcessedPackets();
++ if (player == null) {
++ log.log(Level.SEVERE, "Handling packet for player connection or ticking player connection (null player): " + packetListener);
++ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets);
++ } else {
++ this.dumpEntity(player);
++ net.minecraft.world.entity.Entity vehicle = player.getVehicle();
++ if (vehicle != null) {
++ log.log(Level.SEVERE, "Detailing vehicle for above entity:");
++ this.dumpEntity(vehicle);
++ }
++ log.log(Level.SEVERE, "Total packets processed on the main thread for all players: " + totalPackets);
++ }
++ } else {
++ log.log(Level.SEVERE, "Handling packet for connection: " + packetListener);
++ }
++ }
++ }
++ // Paper end - log detailed tick information
++
+ private WatchdogThread(long timeoutTime, boolean restart)
+ {
+ super( "Paper Watchdog Thread" );
+@@ -119,6 +191,7 @@ public class WatchdogThread extends ca.spottedleaf.moonrise.common.util.TickThre
+ log.log( Level.SEVERE, "------------------------------" );
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
+ ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(MinecraftServer.getServer(), isLongTimeout); // Paper - rewrite chunk system
++ this.dumpTickingInfo(); // Paper - log detailed tick information
+ WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
+ log.log( Level.SEVERE, "------------------------------" );
+ //