BT410 5.3.56: the intermittent pod crash is the skeleton walk's -- attributed by same-binary A/B
Added BT_NO_SKL, which skips the skeleton build so ONE executable can be run with and without it. That is the only clean way to test an intermittent fault, and it settles attribution: walk enabled ~50% of runs die (page fault at 66D9) at DIFFERENT points walk disabled 0 crashes in 2 runs shipped exe 0 crashes in 2 runs, same rig and conf So it is our new code, not the rig, and the varying fault point points at memory corruption surfacing later rather than a bad instruction in the walk. Hypotheses killed by reading the private library headers: the matrix array is the right size (dpl_MATRIX is float32[4][4]); and neither s_dplobject nor the common dpl_node header retains an object name, weakening the dangling-string theory (a private name cache inside the library is still possible and is the best surviving suspect). Also checked something that would have been much worse than a crash: ~NotationFile REWRITES its file when dirty, and these are the game's shipped .SKL data files. MAD.SKL is untouched, and ReadSKLFile now carries the engine's own Verify(!IsDirty()) guard. Next tests are listed cheapest-first in the roadmap: keep the NotationFile alive, copy the Object= names, count board allocations, and re-check whether MakeEntityRenderables runs twice per mech. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -159,6 +159,12 @@ dpl_DCS *
|
||||
<< " -> " << node_count << " nodes, "
|
||||
<< object_count << " objects\n" << flush;
|
||||
|
||||
//
|
||||
// The engine guards this the same way (L4VIDEO.CPP, DPLReadEnvironment):
|
||||
// ~NotationFile REWRITES the file when dirtyFlag is set, and these are
|
||||
// the game's shipped .SKL data files.
|
||||
//
|
||||
Verify(!skeleton->IsDirty());
|
||||
Unregister_Object(skeleton);
|
||||
delete skeleton;
|
||||
return root;
|
||||
@@ -388,6 +394,16 @@ void
|
||||
Logical
|
||||
handled = False;
|
||||
|
||||
//
|
||||
// BT_NO_SKL skips the skeleton build so the SAME binary can be
|
||||
// run with and without it -- the only way to attribute the
|
||||
// intermittent pod crash without a rebuild between samples.
|
||||
//
|
||||
if (getenv("BT_NO_SKL") != NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Entity_Being_Created = entity;
|
||||
video_iterator.First();
|
||||
while ((video_wrapper = video_iterator.ReadAndNext()) != NULL)
|
||||
|
||||
@@ -776,3 +776,49 @@ That defect has therefore gone from background annoyance to the top of the
|
||||
list: it is what stops a mech frame from ever being seen, because a run has
|
||||
to survive BOTH the skeleton build AND the launch to render anything, and at
|
||||
~50% per run that is a coin flip on a four-minute cycle.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
THE INTERMITTENT POD CRASH IS THE SKELETON WALK'S -- attributed, not yet fixed
|
||||
--------------------------------------------------------------------------------
|
||||
Attributed with a same-binary A/B, which is the only clean way to test an
|
||||
intermittent fault: BT_NO_SKL skips the skeleton build, so one executable can
|
||||
be run both ways with nothing else differing.
|
||||
|
||||
walk ENABLED ~50% of runs die ("Reference to a page you don't own",
|
||||
PF at 66D9), at DIFFERENT points each time -- sometimes
|
||||
mid-walk, sometimes after it, sometimes before launch
|
||||
walk DISABLED 0 crashes in 2 runs
|
||||
SHIPPED exe 0 crashes in 2 runs on the same rig and conf
|
||||
|
||||
So it is our new code, it is not the rig, and the varying fault point says
|
||||
memory corruption surfacing later rather than a bad instruction in the walk.
|
||||
|
||||
HYPOTHESES KILLED so far (all by reading the private library headers, so they
|
||||
stay killed):
|
||||
* matrix array too small -- dpl_MATRIX is float32[4][4] (DPL_PRIV.H:137),
|
||||
exactly the 16 floats we pass.
|
||||
* dangling Object= name. dpl_LoadObject is handed a pointer INTO the
|
||||
NotationFile, which we then delete -- but neither s_dplobject
|
||||
(DPL_PRIV.H:377) nor the common dpl_node header (DPL_PRIV.H:92) keeps a
|
||||
name field, so the library does not retain it there. A private name
|
||||
cache is still possible and remains the best surviving suspect.
|
||||
* NotationFile rewriting the game's data. ~NotationFile DOES rewrite the
|
||||
file when dirtyFlag is set, which would have corrupted the shipped .SKL
|
||||
files -- checked, MAD.SKL is untouched (11847 bytes, Jan 2001), and the
|
||||
engine's own Verify(!IsDirty()) guard is now copied into ReadSKLFile.
|
||||
|
||||
STILL TO TRY, cheapest first:
|
||||
1. Keep the NotationFile alive for the mission instead of deleting it (a
|
||||
~12KB leak) and see if the crash rate drops -- that settles the name
|
||||
cache question outright.
|
||||
2. Copy each Object= name into storage that outlives the walk, same test.
|
||||
3. Count what the walk allocates on the board (26 DCS + 19 objects + 19
|
||||
instances + 1 zone per mech) against whatever the VPX HLE's node tables
|
||||
allow -- resource exhaustion would also present as a late, varying
|
||||
fault.
|
||||
4. Check whether MakeEntityRenderables is invoked more than once per mech
|
||||
(inside AND outside views). The [skl] summary line printed once per run
|
||||
here, so this is unlikely, but it is cheap to re-check with two mechs.
|
||||
|
||||
BT_NO_SKL stays in the tree: it is how any future "is it the skeleton?"
|
||||
question gets answered in one build instead of two.
|
||||
|
||||
Reference in New Issue
Block a user