diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index db3cadb2..5224e2ff 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -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) diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 4ee6f586..c3716bab 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.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. diff --git a/docs/re/structures/title-a-press-fault.md b/docs/re/structures/title-a-press-fault.md index 73067e25..a8c4cf7c 100644 --- a/docs/re/structures/title-a-press-fault.md +++ b/docs/re/structures/title-a-press-fault.md @@ -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