Fix two Jul-16 regressions: BT_DEV_GAUGES crash + -net dead controls mapper

Both surfaced today (dormant ~1 day) the moment the pod launch flags
(BT_DEV_GAUGES=1 BT_START_INSIDE=1, tools/mp_launch.sh) were used to drive in
multiplayer -- which made the same-day paint change look guilty.  Confirmed on
the pre-paint build too; the trigger was the Jul-16 audio attribute work.

1) BT_DEV_GAUGES crash (cdb: CoolingLoopConnection::Update, ~15s in as the gauge
   builds lazily).  The dev-gauge cooling-loop lamp reached the cooling master by
   RAW attribute index -- GetAttributePointer(3) + *(master+0x1d4).  The audio
   commits (cc2b109 ReportLeak etc.) inserted rows into the chained attribute
   tables, so index 3 shifted onto a scalar, the resolve walked garbage, and the
   background pass AV'd.  Fix: route through a complete-type bridge reading NAMED
   members (heat.cpp BTCoolingLoopFrame: linkedSinks.Resolve() +
   Condenser::condenserNumber) -- the databinding rule; never a raw numeric
   attribute index.  Removed the now-orphaned GetAttributePointer-by-index
   helper.  Name-keyed samplers (InputVoltage) were unaffected.

2) -net dead controls mapper (mech wouldn't walk; turning/weapons still worked).
   The RIO mapper is built from a stack SubsystemResource in btl4app.cpp that set
   only name/classID/modelSize -- leaving subsystemFlags as stack GARBAGE, which
   Subsystem::Subsystem copies into simulationFlags.  A stray DontExecuteFlag
   (0x2) froze the mapper (speedDemand stuck at 0).  Config-dependent: clean in
   SP, dirty in -net; the audio commits shifted the stack and flipped the bit.
   Fix: memset each hand-built control-mapper resource to 0 (flags 0 =
   AlwaysExecute, the faithful value -- a mapper must tick every frame).

Verified with the pod launch flags: SP alive 32s no crash; MP mech walks
(speedDemand 61.5 at full throttle, ~430u traveled), both nodes alive, no crash.

KB: reconstruction-gotchas.md gains gotcha 18 (uninitialized stack-resource
flags + the raw-attribute-index-into-a-growing-table variant) and a
verify-under-the-user's-launch-flags note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-17 13:58:32 -05:00
co-authored by Claude Opus 4.8
parent e0474ff92a
commit 63250aee41
4 changed files with 104 additions and 27 deletions
+26
View File
@@ -445,6 +445,8 @@ BTL4Application::SharedData
//------------------------------------------------------------
CameraControlsMapper::SubsystemResource
control_subsystem_resource;
// task #7: zero the stack resource (see the mech mapper note below).
memset(&control_subsystem_resource, 0, sizeof(control_subsystem_resource));
Str_Copy(
control_subsystem_resource.subsystemName,
@@ -530,6 +532,14 @@ BTL4Application::SharedData
//
MechControlsMapper::SubsystemResource
control_subsystem_resource;
// task #7 ROOT-CAUSE FIX: Subsystem::Subsystem copies
// model->subsystemFlags into simulationFlags -- an
// uninitialized stack resource left GARBAGE there, and a
// stray DontExecuteFlag bit froze the installed controls
// mapper for the whole session (the -net "can't drive"
// freeze; config-dependent because stack contents are).
// Zero the whole struct before filling it.
memset(&control_subsystem_resource, 0, sizeof(control_subsystem_resource));
Str_Copy(
control_subsystem_resource.subsystemName,
@@ -555,6 +565,14 @@ BTL4Application::SharedData
{
MechControlsMapper::SubsystemResource
control_subsystem_resource;
// task #7 ROOT-CAUSE FIX: Subsystem::Subsystem copies
// model->subsystemFlags into simulationFlags -- an
// uninitialized stack resource left GARBAGE there, and a
// stray DontExecuteFlag bit froze the installed controls
// mapper for the whole session (the -net "can't drive"
// freeze; config-dependent because stack contents are).
// Zero the whole struct before filling it.
memset(&control_subsystem_resource, 0, sizeof(control_subsystem_resource));
Str_Copy(
control_subsystem_resource.subsystemName,
@@ -589,6 +607,14 @@ BTL4Application::SharedData
{
MechControlsMapper::SubsystemResource
control_subsystem_resource;
// task #7 ROOT-CAUSE FIX: Subsystem::Subsystem copies
// model->subsystemFlags into simulationFlags -- an
// uninitialized stack resource left GARBAGE there, and a
// stray DontExecuteFlag bit froze the installed controls
// mapper for the whole session (the -net "can't drive"
// freeze; config-dependent because stack contents are).
// Zero the whole struct before filling it.
memset(&control_subsystem_resource, 0, sizeof(control_subsystem_resource));
Str_Copy(
control_subsystem_resource.subsystemName,