From ad4a970ec96f2e8fa98879560cc1d2985ef22dd5 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 7 Aug 2026 08:14:49 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20#339=20mechanism=20caught=20with=20a=20?= =?UTF-8?q?full=20stack=20=E2=80=94=20packed=20EnvCell=20geom=20id=20hits?= =?UTF-8?q?=20a=2032-bit=20checked=20cast=20on=20the=20render=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Session-B gate launch reproduced the reveal hang at login and the log finally carries the crash: PrepareMeshDataAsync's Setup/GfxObj arm does checked((uint)id) on a packed 64-bit EnvCell geometry id, reached because EnsureRenderDataReady found the id OWNED but DESCRIPTOR-LESS — the release path removes the descriptor while render data parks on the LRU, re-acquire restores ownership, and nothing re-registers the descriptor until a full prepare is re-requested. The OverflowException rides the render frame's readiness evaluation and the reveal is never evaluated again. Demote-then-revisit ordering explains the intermittency. S1B/S2 are not implicated: neither touches this pipeline and the signature predates both. Root-cause fix deliberately NOT designed in this session's tail — the invariant to restore is owned-implies-descriptor (or a legitimate re-request from retained data), which needs the acquire-path read the next session starts with. Catch-and-continue and skip-64-bit-ids are named as the band-aids they are. #343 filed alongside: the wounded render loop's shutdown throws Silk's Reset-inside-render-loop and abandons incomplete, exit 82. Co-Authored-By: Claude Opus 5 --- docs/ISSUES.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/docs/ISSUES.md b/docs/ISSUES.md index f05c933e..7f15f3c3 100644 --- a/docs/ISSUES.md +++ b/docs/ISSUES.md @@ -158,6 +158,17 @@ resolution. --- +## #343 — Shutdown after a wounded render loop: Silk Reset called inside the render loop, exit 82 + +**Status:** OPEN. LOW-MEDIUM — only reachable after a render-frame exception +(#339's crash was the trigger), but it turns a diagnosable failure into an +`AbandonedIncomplete` shutdown. `GameWindowLifetime.ReleaseNativeWindow:294` +calls `ViewImplementationBase.Dispose` → `Reset` while the render loop is +formally still active. Fix belongs with the #339 remediation session. +**Filed:** 2026-08-07 evening, from `session-b-dungeon.log`. + +--- + ## #341 — AD-66's landing is blocked by an unexplained measurement flip on the #331 absorb scenario **Status:** OPEN — HIGH priority for the next physics session; the fix itself @@ -283,7 +294,56 @@ isolation. --- -## #339 — Stuck in portal space: the destination reveal generation never becomes ready +## #339 — Stuck in portal space / at login: the reveal never becomes ready — MECHANISM CAUGHT 2026-08-07 evening, full stack + +**BREAK: the crash is caught.** The Session-B gate launch reproduced the hang +at LOGIN (cell 0xA8B4002F, all readiness flags False forever) and this time +the log carries an unhandled `System.OverflowException` with a full stack: + +``` +ObjectMeshManager.PrepareMeshDataAsync (ObjectMeshManager.cs:1028 region) + <- EnsureRenderDataReady:1302 + <- WbMeshAdapter.IsRenderDataReady:340 + <- LandblockSpawnAdapter.IsLandblockRenderReady:147 + <- GpuWorldState.IsRenderReady:180 + <- StreamingController.IsRenderNeighborhoodResident:280 + <- WorldRevealReadinessBarrier.Prepare:142 + <- WorldRevealCoordinator.PrepareAndEvaluate:188 + <- RuntimeRenderFrameLivePreparation.Prepare +``` + +**The defect:** `PrepareMeshDataAsync` line ~1082 does +`checked((uint)id)` on the Setup/GfxObj arm. EnvCell GEOMETRY ids are packed +64-bit; they are supposed to take the EnvCell arm via `_envCellDescriptors`. +`EnsureRenderDataReady` (line 1302) reaches the fallback when the id is +**owned but descriptor-less**: the release path (`~line 712`) removes the +descriptor while resident render data parks on the LRU; a re-acquire restores +ownership, but nothing re-registers the descriptor until a full EnvCell +prepare is re-requested. A readiness probe arriving in that window falls into +the 32-bit cast and the OverflowException rides the RENDER FRAME path — +after which the reveal is never evaluated again. Demote-then-revisit +ordering explains the intermittency and why the same destination passed +twice earlier: the window only exists after an evict/re-acquire cycle. + +**Status: mechanism established; ROOT-CAUSE FIX NOT YET DESIGNED.** The fix +is NOT "catch the exception" and NOT "skip 64-bit ids" (band-aids both): +the acquire/re-request ordering must make owned-implies-descriptor an +invariant again, or EnsureRenderDataReady must legitimately re-request the +EnvCell prepare from its own retained request data. Next session designs it +against the acquire path (`_ownership` acquire sites vs descriptor +registration at line 965). The S1B/S2 landings are NOT implicated — neither +touches this pipeline, and the readiness signature predates both (the +original filing below). + +**Also spun off this crash: #343** — the shutdown after the wounded render +loop threw `InvalidOperationException: You cannot call Reset inside of the +render loop!` (`GameWindowLifetime.ReleaseNativeWindow:294`), exit 82, +`status=AbandonedIncomplete, blocked=native window`. Secondary, filed +separately below. + +**Original filing:** + +## #339 (original) — Stuck in portal space: the destination reveal generation never becomes ready **Status:** OPEN — observed live 2026-08-07, evidence captured. **Not chased**; user directed it be fixed later.