Source changes (dormant parity infra, retained from iterate 2.AI/2.AO): - xenia-kernel/exports.rs: nt_create_event manual_reset polarity + related event wiring - xenia-gpu/mmio_region.rs: D1MODE_VBLANK_VLINE_STATUS hardcode parity Also lands the audit-runs/ analysis notes (.md/.txt/.json digests) for the iterate 2.x VSync/0x10e8/0x1004 wedge investigation. Raw trace dumps (.jsonl/.gz/.csv/.stdout) and agent worktrees (.claude/) are gitignored as regenerable local artifacts — see memory + HANDOFF for the running findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.7 KiB
4.7 KiB
Phase B — ours changes inventory
All instrumentation is additive and cvar-gated default-off. With
KernelState::phase_b_snapshot_dir == None (the default), the
worker_prologue hook is one Option-tag test; the emitter module is
unreached. Gate 1 verified xenia-rs check --stable-digest -n 50M
produces a byte-identical digest pre/post-patch (see validation.md).
New files
- crates/xenia-kernel/src/phase_b_snapshot.rs — emitter for all five snapshot files + manifest. Stdlib
serde_json+sha2; no new transitive deps beyond what was already pulled into the workspace. ~590 LOC. - tools/diff-state/diff_state.py — stdlib-only Python. Reads both engines' snapshot dirs, classifies divergences by class (σ-structural, δ-content, γ-kernel-content, κ-cache, ε-host-allocator, τ-host-timing), enforces STOP gate on
image_loaded_sha256/xex_entry_point/iso_sha256. ~380 LOC. - tools/diff-state/README.md — usage + rules reference.
Modified files
crates/xenia-app/src/main.rs
- Around line 251: three new
Execflags —--phase-b-snapshot-dir <DIR>,--phase-b-snapshot-and-exit,--phase-b-dump-section-content. - Around line 420: env-var fallback (
XENIA_PHASE_B_SNAPSHOT_DIR,XENIA_PHASE_B_SNAPSHOT_AND_EXIT,XENIA_PHASE_B_DUMP_SECTION_CONTENT); plumbed throughcmd_exec(signature gained three trailing args). - Around line 945:
kernel.entry_pc = entry; kernel.phase_b_snapshot_dir = …;etc. — feeds the resolved values toKernelStatefor the hook to read. - Around line 2228 (
worker_prologue): single hook call intoxenia_kernel::phase_b_snapshot::fire_if_entry_thread(kernel, mem, pc, current_tid), gated bykernel.phase_b_snapshot_dir.is_some()(zero-cost when None). cmd_checkupdated to thread threeNone/falsedefaults so the golden digest path stays unaffected.
crates/xenia-kernel/src/state.rs
- Four new public fields on
KernelState:phase_b_snapshot_dir: Option<PathBuf>,phase_b_snapshot_and_exit: bool,phase_b_dump_section_content: bool,entry_pc: u32. Default-constructedNone/false/0.
crates/xenia-kernel/src/lib.rs
- Adds
pub mod phase_b_snapshot;to the module list (alphabetical position afterobjects).
crates/xenia-kernel/Cargo.toml
- New dependencies:
serde_json(workspace),sha2(workspace, newly added),libc = "0.2"(for_exit).
Cargo.toml (workspace)
- New
sha2 = "0.10"workspace dependency.
Snapshot mechanism
When phase_b_snapshot_dir is Some, the hook in worker_prologue calls
fire_if_entry_thread exactly once. The helper:
- Fast-path early-returns when
phase_b_snapshot_dir == None(Option-tag check). - Returns if
DONEis already set (subsequent slot visits). - Returns if
pc != entry_pc || current_tid != INITIAL_GUEST_TID(this slot visit is not the entry thread's first instruction). - CAS-claims
CLAIMED(one-shot guard against any race). - Calls
write_snapshot, which builds fiveserde_json::Valuetrees, serializes each withserialize_sorted(a deterministic walker that sorts object keys viaBTreeMap-equivalent), writes each viaFile::create + flush + sync_all, indexes the SHA-256s intomanifest.json. - If
phase_b_snapshot_and_exit, callslibc::_exit(0)so the snapshot is durable and the process terminates before the host scheduler or other threads can perturb on-disk state.
What's in each snapshot file (ours side)
| file | content |
|---|---|
cpu_state.json |
pc (= entry_pc), gpr[32] (raw u64 hex), fpr[32] (raw bit-pattern hex), vr[128] + vscr (32-hex BE byte order), cr[8], xer/msr/ctr/lr/vrsave/fpscr, thread_id, stack_base/limit, tls_base, pcr_base. |
memory.json |
regions[] — named ranges (XEX image, main stack, PCR, TLS) each with SHA-256. heaps[] — 4 heap descriptors with committed-page histograms. committed_pages_total. |
kernel.json |
objects[] (sorted by FNV-1a stable handle_semantic_id) — type, type_code, details (per-type fields like thread_id/is_entry_thread). exports_registered_count/sha256/sample[]. |
vfs.json |
resolve_path_probes[] — canonical 10-path probe set. mounted_devices_observed_count. cache_root_listing[]. |
config.json |
xex_entry_point, xex_image_base/size, image_loaded_sha256 (the primary cross-engine invariant), cvars{}, host_ns_at_snapshot / wall_clock_iso8601 (deterministic_skip-flagged). |