Files
xenia-rs/docs/functions/sub_821B6DF4.md
MechaCat02 ad45873a1b ITERATE-2.V: scheduler priority aging closes 18-day AUDIT-049 wedge
Priority aging in xenia-cpu/scheduler.rs:pick_runnable
(effective_priority = base + age_bonus(now_round - last_run_round),
capped at +31, AGING_ROUNDS_PER_BONUS=1). Strict-priority was parking
priority=0 threads behind CPU-bound priority=15 audio mixer
(sub_824D1328 guest spinwait at PC=0x824d1404 on CPU5). Aging
eventually picks the starved thread, breaking the producer-consumer
cycle that caused 5-tid wedge at PC=0x824ac578 since AUDIT-049 (10 May).

Cascade observed: tid=13 clean exit; events 121K -> 13M (107x); last
host_ns 767ms -> 51,011ms (66x); 8 new threads spawn; VdSwap 1 -> 2.

Complete two-day iterate sequence (2026-05-27 -> 2026-05-28):
- 2.F: VdSwap drain timeout 900ms -> 1ms (xenia-gpu/handle.rs); 876x
       perf win on VdSwap kernel callback
- 2.H: vA0000000 physical heap bucket added (state.rs, exports.rs);
       ctx_ptrs now in 0xA0000000-0xBFFFFFFF range matching canary
- 2.L: Phase-A diff harness categorized [return_value mismatch],
       [status mismatch], [args_resolved.path mismatch] tags
       (tools/diff-events/diff_events.py); closes reading-error #41
       (silent test-harness state leak invalidating trace diffs)
- 2.M: always-on exit-thread-state.json sibling to Phase-A JSONL
       (event_log.rs + xenia-app/main.rs); closes reading-error #42
       (Phase-A blind to blocked-forever waits)
- 2.Q: signal.match kernel instrumentation in NtSetEvent /
       NtReleaseSemaphore / KeSetEvent / KeReleaseSemaphore
       (exports.rs); emits target_handle + waiter_count + waiter_tids
- 2.T: wake.requested kernel instrumentation in wake_eligible_waiters
       (exports.rs); emits target_tid + transition + new_state
- 2.V: scheduler priority aging (xenia-cpu/scheduler.rs) [keystone]

Plus accumulated WIP from earlier May (contention_manifest,
phase_b_snapshot, xam/xaudio enhancements, analysis db, xex loader,
xenia-app main loop, etc.). Audit-runs/ artifacts remain untracked
per project convention.

Tests: 300 xenia-cpu / 227 xenia-kernel / 5 xenia-app / 19 xenia-path
/ 30+ smaller suites -- all PASS, 0 regressions. Determinism preserved
(2x cold runs bit-identical at 13,003,881 events post-2.V).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 07:27:26 +02:00

59 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
address: 0x821B6DF4
classification: msvc_eh_catch_handler
confidence: high
last_audit: 060
aliases:
- "AUDIT-058 caller-ladder top (FALSIFIED)"
---
# sub_821B6DF4 — MSVC C++ catch-handler thunk
## Synopsis
A C++ catch-handler thunk emitted by the MSVC PowerPC C++ runtime. Dispatched by the EH machinery (`_CxxFrameHandler3` equivalent) when a matching exception type is thrown — NOT a normal `bl` callee. AUDIT-058 mistakenly treated it as the top of a "static caller ladder" for `sub_825070F0`'s activation; AUDIT-060 falsified that by reading the prolog and the `.rdata` reference context.
**This is the canonical "MSVC EH FuncInfo metadata mistaken for call edges" case. Always check the prolog before assuming a 0-caller fn is a missing activator.**
## Evidence
- Disasm at `0x821B6DF4` opens with the canonical MSVC catch-handler prolog: `subi r31, r12, 112; mflr r12; stwu r1, -96(r1); ...`. The use of `r12` (parent-frame pointer offset) and `mflr r12` is signature MSVC EH-handler shape.
- Address `0x821B6DF4` appears as a u32 value in only two places in the binary:
- `.rdata:0x820C1994` — embedded inside an MSVC FuncInfo struct. Bracketing bytes: `FFFFFFFF 821B6DF4 19930522 00000001 820C1990 ...`. `0x19930522` is the MSVC FuncInfo magic.
- `.pdata:0x8211C678` — exception-unwind metadata.
- AUDIT-060 Probe C-Win Windows Debug canary: `--log_lr_on_pc=0x821B6DF4`, runs at 120s and 240s wallclock → **0 fires both runs**. The matching exception is not thrown at this boot horizon.
- AUDIT-060 Probe O ours: `--ctor-probe=0x821B6DF4 -n 500M`**0 fires**.
- Body: single `bl 0x82183B78` (an EH support routine) then return.
## Activation
C++ exception runtime dispatch. Fires iff a try-block protected by the FuncInfo at `0x820C1990` catches a thrown object whose type matches the catch's CatchTypeInfo. Neither engine throws this exception at the probed horizon.
## Static graph
- Static callers: **0** — and this is correct (0 callers does not imply dead; it implies "not a bl target").
- Callees: `sub_82183B78` (EH support routine).
- xrefs in DB will show `kind=indirect` or absent entries; the `.rdata` reference at `0x820C1994` is the FuncInfo binding, not a call edge.
## Audit log
- **AUDIT-060 (2026-05-12)** — disassembled body; identified MSVC catch-handler prolog; cross-referenced `.rdata` bytes to find FuncInfo magic `0x19930522`; probed in both engines at 240s/-n500M → 0 fires both sides. AUDIT-058's "caller ladder" framing falsified. New reading-error class #16 logged. [confirmed]
- **AUDIT-058 (2026-05-10)** — claimed as "top of static caller ladder" for `sub_825070F0` activation, walked: `sub_825070F0 ← sub_824F7800 ← sub_824F7CD0 ← sub_824F8398 ← sub_821B55D8 ← sub_821B6DF4`. All 6 fire 0× in ours; framed as missing activation. [STATUS: falsified by AUDIT-060 — the entire 6-fn chain is C++ EH unwind metadata; none of them are normal call edges; they fire only on specific exception throws.]
## Open questions
- What exception type-id activates this catch? Parse the FuncInfo struct at `0x820C1990`:
- TryBlockMap entries → CatchTypeArray pointer → CatchType records (each has type_info* + handler ptr).
- The type_info string would identify the C++ class being caught.
- Is the matching throw site reachable in either engine at *any* boot horizon? If yes, when?
- Are the other 5 fns in the AUDIT-058 ladder ALL catch-handler thunks? Spot-check `sub_821B55D8`, `sub_824F8398`, `sub_824F7CD0`, `sub_824F7800`, `sub_825070F0`. (`sub_825070F0` DOES fire 1× per AUDIT-058 — so at least it's not pure-EH; could be the actual throw site or a normal-call leaf.)
## Cross-references
- FuncInfo location: `.rdata:0x820C1990` (start of struct), `0x820C1994` contains this fn's pointer.
- `.pdata` unwind: `0x8211C678`.
- Body callee: `sub_82183B78` (EH support).
- Companion ladder fns (need separate dossiers): `sub_821B55D8`, `sub_824F8398`, `sub_824F7CD0`, `sub_824F7800`, [sub_825070F0](sub_825070F0.md).
- Audits: 058, 060.
- Artifacts: `audit-runs/audit-060-fnptr-array-bootstrap/canary-sub821B6DF4-120s.log`, `canary-sub821B6DF4-240s.log`, `ours-summary.md`.