re: the A-press dialog is the SIGN-IN dialog -- and the corpus already knew
Answers the open half of the A-press diagnosis, and most of the answer was already in the tree. The faulting runs booted with logged_profile_slot_0_xuid = "" -- their own config dump -- while a profile existed (Found 1 Profiles). With nobody signed in, A takes the state-0 branch of sub_821D03A0 and calls XamShowSigninUI(1,1); Canary raises its Sign In dialog with a no-op close handler and nothing in an unattended run dismisses it. 85 instructions verified against the image, 0 mismatches; the state-3 branch is XamShowDeviceSelectorUI, already ruled out by storage_selection_dialog = false. The correlation runs through the tooling: boot_menu.sh passes the profile flag and Q4/Q5 pressed all five buttons; frame_clock.sh, which produced the faulting run, does not. So there is no blocker -- boot with boot_menu.sh. Flagged as retrodicted rather than A/B tested, since I have not myself booted both ways and pressed A. The uncomfortable half: canary-scripted-input-traps.md section 3 already named the sign-in dialog WITH a committed capture, and boot_menu.sh's header already carried the mechanism and the 8.4 million figure. The fault page searched for the cause it had hypothesised and never searched for its own symptom. Added to METHOD.md, along with the more expensive lesson -- a measurement whose only record is a script comment is invisible to the document that needs it. What this session did add is the join: that the known blackout is what drives an unbounded guest queue into a failed 128 MB allocation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
@@ -2651,12 +2651,25 @@ XAM dialog happens to be up is *emulator* state — so "reproduced 4/4" and "it
|
||||
before" were both true all along.
|
||||
|
||||
**For you, concretely:** nothing you ship changes. No disc fact moved, no screen,
|
||||
no timing. What changes is that the questions parked behind this — the BGM loop
|
||||
point (Q10) and whether menu music ducks under a cutscene — are no longer parked
|
||||
behind an unexplained crash. 🟡 They are not unblocked yet either: the route out is
|
||||
one of three (dismiss the dialog, `--headless`, or patch the swallow to return
|
||||
`X_ERROR_EMPTY`), none of them tried, and *which* dialog raises the flag is still
|
||||
unknown. Do not plan around a date.
|
||||
no timing.
|
||||
|
||||
✅ **UPDATE, same day — the dialog is the SIGN-IN dialog, and there is no blocker.**
|
||||
The faulting runs booted with `logged_profile_slot_0_xuid = ""` — a profile exists,
|
||||
none is signed in — so Ⓐ takes the state-0 branch of `sub_821D03A0` and calls
|
||||
`XamShowSigninUI(1, 1)`. Canary raises its Sign In dialog with a no-op close
|
||||
handler, and nothing in an unattended run dismisses it.
|
||||
|
||||
**The route out was already in the tree:** `tools/re-capture/boot_menu.sh` signs the
|
||||
existing profile in, which is why Q4 and Q5 pressed all five menu buttons. ⚠️ Not an
|
||||
A/B I have run myself — treat it as strongly supported rather than demonstrated
|
||||
until someone boots both ways.
|
||||
|
||||
🔴 **And the honest part: the corpus already knew this and my page did not read it.**
|
||||
`canary-scripted-input-traps.md` §3 names the sign-in dialog with a capture, and
|
||||
`boot_menu.sh`'s header quotes the 8.4 M figure. What this session added is the
|
||||
*join* — that the known input blackout is what drives the guest's unbounded
|
||||
keystroke queue into a failed allocation. Recorded in
|
||||
[`METHOD.md`](../re/METHOD.md#before-calling-a-failure-unexplained-grep-the-corpus-for-its-symptom).
|
||||
|
||||
Detail, with the disassembly and the log extract:
|
||||
[`docs/re/structures/title-a-press-fault.md`](../re/structures/title-a-press-fault.md)
|
||||
|
||||
@@ -1146,3 +1146,38 @@ them free calibration points.
|
||||
> random — it is the first N, and what falls in the first N is itself a moving
|
||||
> function of the thing you are measuring.** A truncated view looks like a
|
||||
> complete view of a smaller set.
|
||||
|
||||
## Before calling a failure unexplained, grep the corpus for its *symptom*
|
||||
|
||||
`title-a-press-fault.md` spent a session recording that a single Ⓐ faults the guest
|
||||
4/4, and closed with *"it does not explain how Q4/Q5 pressed Ⓐ successfully; what
|
||||
differs is unfound."*
|
||||
|
||||
**It was found, and written down twice, before that page existed.**
|
||||
|
||||
* [`canary-scripted-input-traps.md`](canary-scripted-input-traps.md) §3: *"With no
|
||||
profile, Ⓐ **is** handled: the guest calls `XamShowSigninUI` and Xenia pops its
|
||||
Sign In dialog"* — with a committed capture.
|
||||
* `tools/re-capture/boot_menu.sh`'s header, which explains the swallow **and quotes
|
||||
the 8.4 million figure**, and is why that launcher passes
|
||||
`--logged_profile_slot_0_xuid`.
|
||||
|
||||
The fault page searched for the *cause* it had hypothesised — an unimplemented
|
||||
instruction, then a wild pointer — and never searched for its own *symptom*, which
|
||||
would have hit both immediately.
|
||||
|
||||
⚠️ **Two lessons, and the second is the expensive one:**
|
||||
|
||||
1. **Grep for the symptom, not the theory.** "Ⓐ", "signin", "IsUIActive" were all in
|
||||
the tree.
|
||||
2. 🔴 **Knowledge in a script header is invisible to the document that needs it.**
|
||||
`boot_menu.sh` had the mechanism and the magnitude, and no `docs/re/` page linked
|
||||
to it. A tool comment is a fine place to explain a flag and a **bad** place to be
|
||||
the only record of a finding. If a script comment is carrying a measurement, that
|
||||
measurement belongs in `docs/re/` with the script pointing at it.
|
||||
|
||||
What the later session did add was the **join** — that this known input blackout is
|
||||
what drives the guest's unbounded keystroke queue into a failed 128 MB allocation —
|
||||
plus the guest code path and a host-vs-guest address retraction. A join between two
|
||||
recorded facts is a real finding; but it is much cheaper when neither fact has to be
|
||||
rediscovered.
|
||||
|
||||
@@ -141,42 +141,86 @@ Evidence: [`../data/a-press-fault-log-extract.txt`](../data/a-press-fault-log-ex
|
||||
crash makes Xenia call `ImGuiDialog::ShowMessageBox` (`emulator.cc:1487`), which is
|
||||
itself a UI — so the swallow can only get worse after the first fault.
|
||||
|
||||
## 🟡 What is still open: *which* dialog
|
||||
## ✅ ANSWERED — it is the **sign-in** dialog, and the run had no profile signed in
|
||||
|
||||
`is_xam_dialog_present_` is a single bool with no logging on the setting side, so the
|
||||
log says a XAM dialog exists and not which one. The static reach:
|
||||
Not a new measurement: **the corpus already had this**, and this page failed to
|
||||
connect to it. [`canary-scripted-input-traps.md`](../canary-scripted-input-traps.md)
|
||||
§3 says it outright — *"With no profile, Ⓐ **is** handled: the guest calls
|
||||
`XamShowSigninUI` and Xenia pops its Sign In dialog"* — with a committed capture,
|
||||
[`title-signin-dialog.png`](../captures/title-signin-dialog.png). And
|
||||
`tools/re-capture/boot_menu.sh`'s own header has carried the mechanism, **including
|
||||
the 8.4 million figure**, since before this page was written.
|
||||
|
||||
* `XamShowDeviceSelectorUI` — **ruled out**. The run's own config dump carries
|
||||
`storage_selection_dialog = false`, and `xam_ui.cc:550` takes the headless path in
|
||||
that case, which never sets the flag.
|
||||
* `XamShowSigninUI` and `XamShowMessageBoxUIEx` — both set it, both are imported, and
|
||||
both reach the guest. `sub_821D03A0` calls the game's `XamShowSigninUI` **and**
|
||||
`XamShowDeviceSelectorUI` wrappers, which is the shape of a "sign in, then pick
|
||||
storage" flow — exactly what a title screen's Ⓐ would start.
|
||||
* `XamShowKeyboardUI`, `XamShowDirtyDiscErrorUI` — imported; not excluded, but neither
|
||||
fits the moment.
|
||||
### The run's own config dump says the profile was not signed in
|
||||
|
||||
**The experiment that settles it** is one line of Canary, not another blind boot: log
|
||||
the function name at each `is_xam_dialog_present_.store(true)` site in `xam_ui.cc`.
|
||||
Recorded rather than done, because it is an emulator change and this iteration's
|
||||
budget went to the diagnosis.
|
||||
```
|
||||
[Profiles]
|
||||
create_profile_if_none = ""
|
||||
logged_profile_slot_0_xuid = "" ← nobody logged in
|
||||
...
|
||||
i> FindProfiles: Adding profile B13EBABEBABEBABE to profile list
|
||||
i> ProfileManager: Found 1 Profiles ← a profile EXISTS, it is just not signed in
|
||||
```
|
||||
|
||||
### And the call site is now located in the image, not only observed
|
||||
|
||||
`sub_821D03A0` is the state machine that raises it, verified byte-for-byte
|
||||
(**85 instructions, 0 mismatches**):
|
||||
|
||||
| state at `[[r31+8]+4]` | branch | call |
|
||||
|---|---|---|
|
||||
| **0** | `0x821D04CC` | `li r4,1; li r3,1; bl 0x824A9068` → thunk `0x8284DA8C` = **`XamShowSigninUI(1, 1)`** |
|
||||
| **3** | `0x821D04A4` | `bl 0x824A9080` → `0x8284DABC` = `XamShowDeviceSelectorUI` |
|
||||
| other | — | nothing |
|
||||
|
||||
So the two candidates this page listed are both real branches of one function, and
|
||||
the run took the **state-0** one. The device selector was already ruled out by
|
||||
`storage_selection_dialog = false`; this identifies the other by address rather
|
||||
than by elimination.
|
||||
|
||||
Canary's `xeXamShowSigninUI` then sets the flag and dispatches `ui::SigninUI`
|
||||
**asynchronously with a no-op close handler** — so in an unattended run nothing
|
||||
ever dismisses it, and the swallow is permanent.
|
||||
|
||||
### The correlation runs through the tooling, not just this one log
|
||||
|
||||
| launcher | passes `--logged_profile_slot_0_xuid` | Ⓐ outcome |
|
||||
|---|---|---|
|
||||
| `boot_menu.sh` | **yes** | Q4/Q5 pressed all five menu buttons |
|
||||
| `frame_clock.sh` (this run) | **no** | faulted, 4/4 |
|
||||
|
||||
### 🔴 The process failure, which is the part worth keeping
|
||||
|
||||
This page said *"it does not explain how Q4/Q5 pressed Ⓐ successfully; what differs
|
||||
is unfound."* **It was found, twice, and written down in two places this page did
|
||||
not read** — a sibling `docs/re/` page and a tool header. The corpus knew the
|
||||
swallow and knew the profile requirement; nobody had joined either to the crash.
|
||||
|
||||
What this session actually adds is the **join**: that the known input blackout is
|
||||
what drives an unbounded guest queue into a failed 128 MB allocation, with the
|
||||
counter and the register file agreeing to 7. Recorded in
|
||||
[`METHOD.md`](../METHOD.md).
|
||||
|
||||
## What this unblocks, and how
|
||||
|
||||
The blocked list — main-menu sweeps, whether a `.tbm` draws pixels, `pbafc.prm`'s
|
||||
blend — needs a screen behind an Ⓐ press. Three routes now exist where before there
|
||||
were none, in cost order:
|
||||
blend — needs a screen behind an Ⓐ press.
|
||||
|
||||
1. **Dismiss the dialog.** It is an ImGui window on the emulator surface; the run had
|
||||
a display. If it can be clicked or key-dismissed, the flag clears and the pump
|
||||
drains normally. Cheapest, and testable in one boot.
|
||||
2. **`--headless`.** Both `xeXamShowSigninUI` and `XamShowMessageBoxUIEx` take a
|
||||
dispatch-headless path that never sets the flag. ⚠️ It also removes the window the
|
||||
capture harness grabs, so this trades the fault for a different blocker.
|
||||
3. **Patch the swallow.** Returning `X_ERROR_EMPTY` instead of `X_ERROR_SUCCESS` at
|
||||
`xam_input.cc:217` terminates the pump immediately and is closer to hardware
|
||||
(a real Xbox does not hand a game an infinite run of empty keystrokes). This is
|
||||
an emulator change and needs to be recorded as one wherever it is used.
|
||||
✅ **There is no blocker. Boot with `tools/re-capture/boot_menu.sh`**, which signs
|
||||
the existing profile in, and the state-0 branch never fires. That is the launcher
|
||||
Q4 and Q5 used, and it has been in the tree the whole time.
|
||||
|
||||
⚠️ **This is a prediction retrodicted, not an A/B I ran.** The mechanism is measured
|
||||
and the launcher difference is documented, and Q4/Q5 are the oracle evidence that
|
||||
Ⓐ works under `boot_menu.sh` — but I have not myself booted both ways and pressed Ⓐ.
|
||||
Until someone does, treat "signing the profile in prevents the fault" as strongly
|
||||
supported rather than demonstrated.
|
||||
|
||||
If it ever needs a belt-and-braces second route, patching `xam_input.cc:217` to
|
||||
return `X_ERROR_EMPTY` instead of `X_ERROR_SUCCESS` terminates the pump immediately
|
||||
and is closer to hardware — a real Xbox does not hand a game an infinite run of
|
||||
empty keystrokes. That is an emulator change and must be recorded as one wherever
|
||||
it is used.
|
||||
|
||||
⚠️ **Whichever route is taken, keep `tools/re-capture/frame_clock.sh`'s size guard.**
|
||||
It killed this run at its 300 MB cap and worked exactly as designed; without it the
|
||||
|
||||
Reference in New Issue
Block a user