mirror of
https://github.com/PaperMC/Paper.git
synced 2024-10-31 07:49:57 +01:00
297 lines
15 KiB
Diff
297 lines
15 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||
|
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 23757f466da571aec35a373112dcbba0d1f46dcb..3321bb7582a3e0227fbc1d41982529c23548269b 100644
|
||
|
--- a/src/main/java/net/minecraft/network/Connection.java
|
||
|
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||
|
@@ -481,7 +481,14 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||
|
}
|
||
|
|
||
|
if (this.packetListener instanceof ServerGamePacketListenerImpl) {
|
||
|
+ // Paper start - detailed watchdog information
|
||
|
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.push(this.packetListener);
|
||
|
+ try {
|
||
|
+ // Paper end - detailed watchdog information
|
||
|
((ServerGamePacketListenerImpl) this.packetListener).tick();
|
||
|
+ } finally { // Paper start - detailed watchdog information
|
||
|
+ net.minecraft.network.protocol.PacketUtils.packetProcessing.pop();
|
||
|
+ } // Paper start - detailed watchdog information
|
||
|
}
|
||
|
|
||
|
if (!this.isConnected() && !this.disconnectionHandled) {
|
||
|
diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java
|
||
|
index bcf53ec07b8eeec7a88fb67e6fb908362e6f51b0..acc12307f61e1e055896b68fe16654c9c4a606a0 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 = LogManager.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 {
|
||
|
@@ -30,6 +48,8 @@ public class PacketUtils {
|
||
|
if (!engine.isSameThread()) {
|
||
|
Timing timing = MinecraftTimings.getPacketTiming(packet); // Paper - timings
|
||
|
engine.execute(() -> {
|
||
|
+ packetProcessing.push(listener); // Paper - detailed watchdog information
|
||
|
+ try { // Paper - detailed watchdog information
|
||
|
if (MinecraftServer.getServer().hasStopped() || (listener instanceof ServerGamePacketListenerImpl && ((ServerGamePacketListenerImpl) listener).processedDisconnect)) return; // CraftBukkit, MC-142590
|
||
|
if (listener.getConnection().isConnected()) {
|
||
|
try (Timing ignored = timing.startTiming()) { // Paper - timings
|
||
|
@@ -53,6 +73,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 12b13945702a03132d1b4c42864c8036d1357020..b5a2445bbd691cbfed0d0bf7c688b1f10c267039 100644
|
||
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||
|
@@ -962,7 +962,26 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||
|
|
||
|
}
|
||
|
|
||
|
+ // 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
|
||
|
+ io.papermc.paper.util.TickThread.ensureTickThread("Cannot tick an entity off-main");
|
||
|
+ try {
|
||
|
+ if (currentlyTickingEntity.get() == null) {
|
||
|
+ currentlyTickingEntity.lazySet(entity);
|
||
|
+ }
|
||
|
+ // Paper end - log detailed entity tick information
|
||
|
++TimingHistory.entityTicks; // Paper - timings
|
||
|
// Spigot start
|
||
|
co.aikar.timings.Timing timer; // Paper
|
||
|
@@ -1002,7 +1021,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||
|
this.tickPassenger(entity, entity1);
|
||
|
}
|
||
|
// } finally { timer.stopTiming(); } // Paper - timings - move up
|
||
|
-
|
||
|
+ // 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) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
index 481e84fda6dccfaf684c922a12fa19ed35c87b3c..94857a736d2a16e8ade286c6f2ddf8bd798008eb 100644
|
||
|
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||
|
@@ -888,7 +888,42 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||
|
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 movementType, Vec3 movement) {
|
||
|
+ // Paper start - detailed watchdog information
|
||
|
+ io.papermc.paper.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 {
|
||
|
@@ -1079,6 +1114,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||
|
this.level.getProfiler().pop();
|
||
|
}
|
||
|
}
|
||
|
+ // Paper start - detailed watchdog information
|
||
|
+ } finally {
|
||
|
+ synchronized (this.posLock) { // Paper
|
||
|
+ this.moveVector = null;
|
||
|
+ } // Paper
|
||
|
+ }
|
||
|
+ // Paper end - detailed watchdog information
|
||
|
}
|
||
|
|
||
|
protected void tryCheckInsideBlocks() {
|
||
|
@@ -3896,7 +3938,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||
|
}
|
||
|
|
||
|
public void setDeltaMovement(Vec3 velocity) {
|
||
|
+ synchronized (this.posLock) { // Paper
|
||
|
this.deltaMovement = velocity;
|
||
|
+ } // Paper
|
||
|
}
|
||
|
|
||
|
public void setDeltaMovement(double x, double y, double z) {
|
||
|
@@ -3972,7 +4016,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||
|
}
|
||
|
// 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 dcfbe77bdb25d9c58ffb7b75c48bdb580bc0de47..bee38307494188800886a1622fed229b88dbd8f1 100644
|
||
|
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||
|
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||
|
@@ -23,6 +23,78 @@ public class WatchdogThread extends Thread
|
||
|
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 = entity.getMinecraftKey().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" );
|
||
|
@@ -121,6 +193,7 @@ public class WatchdogThread extends Thread
|
||
|
log.log( Level.SEVERE, "------------------------------" );
|
||
|
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||
|
com.destroystokyo.paper.io.chunk.ChunkTaskManager.dumpAllChunkLoadInfo(); // Paper
|
||
|
+ this.dumpTickingInfo(); // Paper - log detailed tick information
|
||
|
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( server.serverThread.getId(), Integer.MAX_VALUE ), log );
|
||
|
log.log( Level.SEVERE, "------------------------------" );
|
||
|
//
|