aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch')
-rw-r--r--patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch57
1 files changed, 57 insertions, 0 deletions
diff --git a/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch b/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch
new file mode 100644
index 0000000000..206968f773
--- /dev/null
+++ b/patches/server/1030-Add-debug-for-chunk-system-unload-crash.patch
@@ -0,0 +1,57 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Wed, 19 Jun 2024 10:52:07 -0700
+Subject: [PATCH] Add debug for chunk system unload crash
+
+Somehow, a chunkholder is present in the unload queue after
+it has been unloaded. It is likely that this is a result of
+adding the chunk holder to the unload queue while it is
+unloading. However, that should not be possible.
+
+To find out where it is being added to the unload queue, track
+the last stacktrace which adds to the unload queue and check
+on chunk holder remove if the holder is present in the unload queue
+and log the stacktrace.
+
+diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
+index 1dfddea4fd7e89fb6fd9fa49f7ab5e6f48e6ef3c..4068138e4ec0ccb02f5925f8b5a31381882f08e0 100644
+--- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
++++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java
+@@ -749,9 +749,22 @@ public final class NewChunkHolder {
+
+ /** Unloaded from chunk map */
+ private boolean unloaded;
++ private Throwable lastUnloadAdd;
+
+ void markUnloaded() {
+ this.unloaded = true;
++ if (this.inUnloadQueue) {
++ if (this.lastUnloadAdd != null) {
++ LOGGER.error("Unloaded chunkholder " + this.toString() + " while in the unload queue", this.lastUnloadAdd);
++ } else {
++ // should never happen
++ LOGGER.error("Unloaded chunkholder " + this.toString() + " while in the unload queue without a throwable");
++ }
++
++ // prevent crash by removing (note: we hold scheduling lock here)
++ this.inUnloadQueue = false;
++ this.scheduler.chunkHolderManager.unloadQueue.removeChunk(this.chunkX, this.chunkZ);
++ }
+ }
+
+ private boolean inUnloadQueue = false;
+@@ -769,12 +782,14 @@ public final class NewChunkHolder {
+ // ensure in unload queue
+ if (!this.inUnloadQueue) {
+ this.inUnloadQueue = true;
++ this.lastUnloadAdd = new Throwable();
+ this.scheduler.chunkHolderManager.unloadQueue.addChunk(this.chunkX, this.chunkZ);
+ }
+ } else {
+ // ensure not in unload queue
+ if (this.inUnloadQueue) {
+ this.inUnloadQueue = false;
++ this.lastUnloadAdd = null;
+ this.scheduler.chunkHolderManager.unloadQueue.removeChunk(this.chunkX, this.chunkZ);
+ }
+ }