The database mount below was one of three ways the decoder could not reach its own oracle. The other two are here. `run-canary` never looked in `Checked/`. It tried `Release/` then `Debug/`, and both of those exist on this box -- an Aug 28 binary and a Jul 19 one. They boot the game perfectly well and carry NO `audit_61` branch probe, so a probe run against either returns zero hits that read as a finding about the game rather than as a stale binary. Configuration is now the outer loop and location the inner one, so a `Checked` build anywhere beats a `Release` build anywhere; `$XENIA_BIN` still overrides everything. Measured here: `Checked` has `audit_61_branch_probe_pcs`, `Release` and `Debug` do not. The launcher also now says which instrumentation is missing BEFORE the run, because the alternative is reading an empty log afterwards and guessing. `build-canary` built `$PROJECT_DIR/xenia-canary`, which does not exist in this container -- the source is bind-mounted at `/canary` and the launcher already exports `XENIA_SRC=/canary`. CONTAINER-NOTES has carried that defect since 2026-08-29 with a symlink workaround and a warning to remember to delete the symlink afterwards. It now reads `$XENIA_SRC` first, so there is nothing to remember. Its default configuration moves Release -> Checked to match what `run-canary` picks; the old default spent a full build on a binary nothing ran. Two documented blockers are refuted rather than deleted, since the sequence of wrong readings is what makes the right one checkable: the CONTAINER-NOTES symlink dance (the warm build volume it was configured against is gone too, removed in the 2026-09-18 cleanup, so the next build configures cleanly against `/canary`), and `upstream-baseline.md`'s "`version.h` is never generated" -- `CMakeLists.txt` generates it at configure time now, with a stub fallback. `decoder-loop.md` claimed the oracle was at `Linux/Release/` and that the probe was on two side branches; both were true when written and neither is now. Verified: five pick_bin cases against the extracted function body, and `strings` on all three real binaries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
92 lines
4.6 KiB
Markdown
92 lines
4.6 KiB
Markdown
# A stock-upstream baseline runs Stage 02 crash-free
|
|
|
|
**Status:** ✅ `CONFIRMED` — upstream `canary_experimental` + **only** the pad
|
|
driver and the threading fix reaches Stage 02 flight with **zero** crash dumps,
|
|
where the instrumented branch produces 384 at the briefing and never reaches
|
|
flight. 🔴 pure upstream on its own is **less** stable, not more — it still has
|
|
the lost-resume race. 🔴 the `REMAINING OB` address is **not** found: the first
|
|
candidate was refuted.
|
|
|
|
## Why this was tried
|
|
|
|
The instrumented branch stops at the Stage 02 briefing under a storm of
|
|
`0x82307128` ([`title-crash-stl-tree.md`](title-crash-stl-tree.md)). The question
|
|
"is that crash ours or upstream's?" is answerable by building upstream clean.
|
|
|
|
## Building it, and two tooling gaps found on the way
|
|
|
|
`git fetch upstream` works from this container. The merge base is 82 commits
|
|
behind `upstream/canary_experimental` (`a5a18f5c7`); our branch carries 50 of its
|
|
own.
|
|
|
|
* ~~**`version.h` is never generated.**~~ ✅ **FIXED — `CMakeLists.txt` now
|
|
generates it at configure time**, calling `xenia-build.py`'s
|
|
`generate_version_h()` and falling back to a stub if that fails, so a
|
|
CMake-direct build no longer depends on a stale copy in the build directory.
|
|
It used to fail on `trace_writer.cc:17: fatal error: 'version.h' file not
|
|
found`, and the fix had to exist before the 2026-09-18 cleanup deleted the
|
|
build volume that was carrying that stale copy.
|
|
* **`build-canary` reports success on a failed build.** The harness recorded
|
|
"completed (exit code 0)" while ninja had stopped with `1 error generated`.
|
|
Only the missing binary gave it away.
|
|
|
|
## Pure upstream cannot be driven — and is not more stable
|
|
|
|
`--hid=file` is **ours** (`d15c8cfab` and two follow-ups), and there is no uinput
|
|
in this container, so a genuinely pure binary boots but cannot be scripted past
|
|
the title. The honest baseline is therefore **upstream + those three commits**.
|
|
|
|
That baseline reproduced the **lost resume** on its second boot: black screen,
|
|
guest alive at **522 % CPU**, the newest host thread at **`00:00:00`** CPU time,
|
|
its guest handle making zero kernel calls — the exact signature from
|
|
[`canary-scripted-input-traps.md`](canary-scripted-input-traps.md). Reading
|
|
`upstream/canary_experimental:src/xenia/base/threading_posix.cc` confirms the
|
|
two-lock-scope publish is still there. **So "pure upstream" is not a stable
|
|
state: it contains a real bug this project had already fixed.**
|
|
|
|
## ✅ Upstream + the threading fix: Stage 02, in flight, zero crashes
|
|
|
|
Adding **only** `a60fe7d11` on top — still none of the RE instrumentation —
|
|
`launch_mission.sh` drove boot → title → LOAD GAME → slot 01 → READY ROOM →
|
|
TAKE OFF → **flight**:
|
|
|
|

|
|
|
|
`TIME 05:03.75`, wingman `Rhino 103 / Ellen Bernstein`, radio dialogue, asteroids,
|
|
tracer fire — and **`REMAINING OB 020`** with `OB` badges on the objective
|
|
targets. The run ended in a legitimate **GAME OVER** (the unattended craft was
|
|
shot down, exactly as `autopilot-memory-driven.md` warns) — **not** a crash.
|
|
|
|
**Crash dumps for the entire run: 0.** Against 384 on the instrumented branch at
|
|
the briefing alone.
|
|
|
|
So the mission crash is **not upstream's**. It is either in our 50 commits or
|
|
fixed among upstream's 82 — this run does not separate those two, and saying
|
|
which would need a bisect.
|
|
|
|
## 🔴 `REMAINING OB` in RAM: first candidate refuted
|
|
|
|
The counter is visible and moves (020 → 019 → 018 → 017), so it is scannable.
|
|
|
|
* A three-snapshot big-endian u32 filter (19 → 19 → 18) left **0** survivors.
|
|
* A direct differential across widths over the 19→18 transition gave exactly
|
|
**one** aligned BE u32: `va 0xbc22e83c` (the u16 hit at `…83e` is its low half).
|
|
* **Refuted.** Read live moments later it held **26** while the HUD showed
|
|
**017**. It is an unrelated counter that happened to step 19→18 in the same
|
|
window.
|
|
|
|
That the u32 filter came back empty is itself a result: the counter is not a
|
|
plain persistent big-endian word. Candidates worth trying next are a per-digit
|
|
representation, a value recomputed each frame from an entity list (in which case
|
|
the *list* is the real target), or a field inside a structure that moves.
|
|
|
|
## Not settled
|
|
|
|
* 🔴 Which side owns the mission crash — our 50 commits or upstream's 82. A
|
|
bisect would say; nothing cheaper will.
|
|
* 🔴 The `REMAINING OB` address.
|
|
* ⚠️ `wait_flight.sh` reported `NEVER REACHED FLIGHT` while the game was plainly
|
|
in flight — its detector is wrong, and `screen_id.py` got it right.
|
|
* ⚠️ Any future in-mission scan needs the pilot flying or a safe holding pattern:
|
|
an idle craft is dead in about a minute.
|