Two defects that were masking each other, both now fixed and benched.
1) THE LATCH NEVER RELEASED ON FAILURE. The binary's FUN_004c012c tail is
Post(...) ; *(this+0x290)=0 ; *(this+0x258)=0 (part_013.c:10519-10523).
We had the Post and the suppressConsole and were missing the middle
instruction, so deathPending cleared only on SUCCESS paths. One failed
respawn latched the pilot for the whole mission: every later death hit the
dedup and was SWALLOWED, so the cycle could never restart -- a transient
hiccup became a PERMANENT ghost (dead, un-Reset, still driveable, a burning
wreck on every peer that sinks after ~18s and can never be drawn again).
Binary evidence: +0x290 is written in exactly THREE places in all of
BTL4OPT.EXE (0x0b75fb, 0x0bffe3, 0x0c0a05) and all three store a ZEROED
register; there is no write of 1 -- or any non-zero, in any instruction form
-- anywhere. The dedup gate itself IS authentic (@004c05c4 does
mov edx,[ebx+0x290]; test edx,edx; jne ret), so it is kept.
2) VehicleDeadMessage WAS DISPATCHED TWICE PER DEATH. BTPostKillScore
(btplayer.cpp:2263) sent a second one "to credit a death", but that message
is the RESPAWN-CYCLE TRIGGER, not a scoreboard increment, and the tally is
already credited by the handler's ++deathTally (:538). Both fire inside the
same death transition (BTPostKillScore at mech4.cpp:2006, the hardened
authentic notify at :2110), so they were always paired. Removed; the kill
credit above it is untouched (it correctly uses a ScoreMessage).
THEY HID EACH OTHER: the duplicate made the latch look necessary, and the latch
made the duplicate invisible. Every "death ... SWALLOWED" warning in the field
logs was just the latch deduping our own duplicate -- 8 of 8 deaths, a 100% base
rate, which is exactly why it correlated with nothing when tested. Fixing
either alone makes things visibly worse (the first bench of fix 1 alone produced
a DOUBLE cycle: deathCount double-incremented, cycle 1's re-post gone stale and
tripping the drop-zone MISMATCH). That is why earlier passes at #57/#55 kept
adding clear-sites instead of finding the root; the binary broke the tie.
VERIFIED
solo: 17 consecutive death/respawn cycles, every one START->RESET,
0 swallowed / 0 mismatch / 0 crash. Pre-fix this strands permanently
after cycle 1.
MP : two nodes over a real network path with cross-machine drop-zone replies
(each node's request is answered by the OTHER machine) -- A 11 cycles,
B 12, 0 swallowed / 0 mismatch / 0 discarded / 0 crash.
harness: BT_SELF_DAMAGE_REPEAT=1 re-arms the self-damage bench after respawn
so multiple cycles can be driven (a one-death harness can never
exercise this fix). scratchpad/night6/mp_ghost.sh.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.2 KiB
Bash
32 lines
1.2 KiB
Bash
#!/usr/bin/env bash
|
|
# #81 GHOST REPRO: two nodes, BOTH die, watch the respawn handshake.
|
|
#
|
|
# Looking for, on either node:
|
|
# [dzreq] ... msgDeath= ourDeathCount= (the request side)
|
|
# [dz] GRANTED / STALL (the drop zone's answer)
|
|
# [ghost] DROP-ZONE REPLY DISCARDED (the silent-discard path)
|
|
# [respawn] ... RESET at drop zone (success)
|
|
# A node with a death cycle START and no RESET has reproduced the field ghost.
|
|
set -x
|
|
cd /c/git/bt411/content || exit 1
|
|
rm -f mp_a.log mp_b.log
|
|
sed 's/^experience=expert/experience=novice/' MP.EGG > MPG.EGG
|
|
|
|
# B first (listener), then A -- same order as the working mp_skate.sh
|
|
BT_LOG=mp_b.log BT_AFFINITY=0x2 BT_MP_LOG=1 BT_SCORE_LOG=1 BT_DEATH_LOG=1 \
|
|
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_DELAY=40 BT_SELF_DAMAGE_REPEAT=1 \
|
|
../build/Release/btl4.exe -egg MPG.EGG -net 1601 &
|
|
sleep 2
|
|
BT_LOG=mp_a.log BT_AFFINITY=0x1 BT_MP_LOG=1 BT_SCORE_LOG=1 BT_DEATH_LOG=1 \
|
|
BT_SELF_DAMAGE=60 BT_SELF_DAMAGE_DELAY=55 BT_SELF_DAMAGE_REPEAT=1 \
|
|
../build/Release/btl4.exe -egg MPG.EGG -net 1501 &
|
|
sleep 4
|
|
python ../tools/btconsole.py MPG.EGG 127.0.0.1:1501 127.0.0.1:1601 &
|
|
PC=$!
|
|
|
|
sleep 175
|
|
kill $PC 2>/dev/null
|
|
taskkill //F //IM btl4.exe 2>/dev/null
|
|
rm -f MPG.EGG
|
|
echo "=== DONE ==="
|