aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch')
-rw-r--r--patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch57
1 files changed, 57 insertions, 0 deletions
diff --git a/patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch b/patches/server/1031-Add-debug-for-chunk-system-unload-crash.patch
new file mode 100644
index 0000000000..401b927f05
--- /dev/null
+++ b/patches/server/1031-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 d5fc5756ea960096ff23376a6b7ac68a2a462d22..0715514c8bb49c805b04f42ff37903a7d590aaa8 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
+@@ -748,9 +748,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;
+@@ -768,12 +781,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);
+ }
+ }