Crash self-report + round-completed latch + PDB archiving

CRASH SELF-REPORT (the #35/#41 heisenbug hunt): every unhandled
exception now logs its code, address, and an EBP-walked stack as
module-relative offsets (btl4+0xNNNN) into BT_LOG before dying --
any field crash on any machine hands us a resolvable stack.  The
walker is per-dereference guarded (a corrupt chain truncates).
BT_CRASHTEST=1 exercises the path end-to-end (verified: forced AV
logs code/addr/5-frame stack).  mkdist archives each build's PDB
next to its zip so offsets resolve per distributed version.

Context: a flaky release-only crash in the mech build path surfaced
during #38 rigs -- it moves with build layout, spares neither peer,
and masks under a debugger heap (13 clean cdb runs vs 2/3 crashes
without).  A real latent memory bug; the self-report will catch it
wherever it strikes next.

ROUND-COMPLETED LATCH (issue #38, awaiting verification): relay-mode
clients refuse RunMission after a round has ended -- the lobby-loop
relaunch owns the next round (in-process round 2 rebuilt every
player/mech entity on stale globals; matchlog caught player=3:1->3:36
in one generation).  Latch sets ONLY when the stop ends a RUNNING
mission (a stray pre-mission StopMission must not poison round 1 --
the first cut ate a legit launch, caught + fixed in rig).  Regression
verification pending (contaminated by the heisenbug above).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-24 08:51:50 -05:00
co-authored by Claude Opus 4.8
parent ac7f0cb13a
commit f7daf03507
4 changed files with 113 additions and 0 deletions
+13
View File
@@ -1724,6 +1724,19 @@ void
extern int gBTMissionStoppedByConsole;
gBTMissionStoppedByConsole = 1;
}
// Issue #38: the round is over -- latch it (relay mode refuses further
// in-process RunMissions; the relaunch owns the next round) and void
// any stale mid-load launch pends so they can't fire post-round.
// ONLY when this stop ends a mission that actually RAN: a stray
// pre-mission StopMission (relay races) must not poison the round-1
// launch (caught live: the latch ate RunMission #2 of round one).
if (GetApplicationState() == RunningMission)
{
extern int gBTRoundCompleted;
extern int gBTRunMissionPendCount;
gBTRoundCompleted = 1;
gBTRunMissionPendCount = 0;
}
//
//--------------------------------------------------------------------------