handoff: VSync/event-wedge fixes + iterate 2.A–2.BC research notes
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>
This commit is contained in:
114
audit-runs/phase-c6-call-name-divergence/re-validation.md
Normal file
114
audit-runs/phase-c6-call-name-divergence/re-validation.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Phase C+6 — re-validation
|
||||
|
||||
## Gate 1 — Determinism (cvar-OFF, ours)
|
||||
|
||||
3 fresh runs of `check -n 50000000 --stable-digest`:
|
||||
|
||||
| run | digest md5 |
|
||||
|-----|------------|
|
||||
| 1 | c6d895829b4611964978990ae1cb8a6a |
|
||||
| 2 | c6d895829b4611964978990ae1cb8a6a |
|
||||
| 3 | c6d895829b4611964978990ae1cb8a6a |
|
||||
| C+5 baseline (cvar-OFF) | `c6d895829b4611964978990ae1cb8a6a` |
|
||||
|
||||
**Result**: ✅ byte-identical across 3 runs and SAME as the C+5
|
||||
baseline. The Phase C+6 fix is purely an emitter-framing change (cvar
|
||||
`phase_a_event_log` OFF path): the `unimplemented_exports` HashSet is
|
||||
consulted only inside the `phase_a_on` guard in `call_export`. The
|
||||
stub body (`stub_success`, which sets `r3 = 0`) still runs unchanged.
|
||||
Therefore the cvar-OFF deterministic boot trajectory is unchanged.
|
||||
Baseline digest preserved.
|
||||
|
||||
## Gate 2 — Phase B `image_canonical_sha256`
|
||||
|
||||
Phase B snapshot captured to `snap/ours/`.
|
||||
`image_loaded_sha256 = ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18`
|
||||
matches the Phase-A/B verify baseline. The fix touches only the
|
||||
kernel-export shim/emitter layer — no PE image bytes modified.
|
||||
|
||||
## Gate 3 — Phase A matched-prefix extension (KEY METRIC)
|
||||
|
||||
Diffed `audit-runs/phase-c6-call-name-divergence/ours.jsonl` against
|
||||
the existing `phase-c-first-divergence/phase-a/canary.jsonl`.
|
||||
|
||||
| chain | C+5 (pre-C+6) | C+6 (post) | Δ |
|
||||
|---|---|---|---|
|
||||
| canary tid=6 → ours tid=1 (main) | 102132 | **102158** | **+26** |
|
||||
| canary tid=4 → ours tid=11 | 5 | 5 | 0 |
|
||||
| canary tid=7 → ours tid=2 | 15 | 15 | 0 |
|
||||
| canary tid=12 → ours tid=7 | 2 | 2 | 0 |
|
||||
| canary tid=14 → ours tid=9 | 39 | 39 | 0 |
|
||||
| canary tid=15 → ours tid=10 | (no div) | (no div) | 0 |
|
||||
|
||||
**Main thread matched prefix grew from 102132 to 102158. Gate 3 ✅.**
|
||||
|
||||
The new first-divergence at idx=102158 is `XamTaskCloseHandle`
|
||||
`return_value`: canary=1, ours=0 — value divergence, NOT a call-name
|
||||
divergence. That's the next Phase C+N target.
|
||||
|
||||
## Gate 4 — Build
|
||||
|
||||
```
|
||||
$ cargo build --release
|
||||
Compiling xenia-kernel v0.1.0
|
||||
Compiling xenia-app v0.1.0
|
||||
Finished `release` profile [optimized] target(s) in 6.22s
|
||||
```
|
||||
|
||||
One pre-existing dead-code warning (`walk_committed_regions`); not
|
||||
introduced by this fix. Canary untouched.
|
||||
|
||||
## Gate 5 — Phase A determinism (emitter)
|
||||
|
||||
Two cvar-ON captures of the same engine binary on the same ISO,
|
||||
md5-summing only deterministic fields (excluding `host_ns` AND
|
||||
`guest_cycle` — both are timing-sensitive, see Stage 2's
|
||||
established practice):
|
||||
|
||||
```
|
||||
ours.jsonl (run 1, det-fields-only) 7312446e49fa3c3149d26424832cabf4
|
||||
/tmp/c6_pa_run2.jsonl (run 2, det-fields-only) 7312446e49fa3c3149d26424832cabf4
|
||||
```
|
||||
|
||||
Byte-identical. ✅
|
||||
|
||||
Note: digest changes from C+5's `388d394a…` because the suppression
|
||||
flips 3 events on/off in the deterministic-fields stream. Expected.
|
||||
|
||||
## Gate 6 — Kernel unit tests
|
||||
|
||||
```
|
||||
$ cargo test --release -p xenia-kernel --lib
|
||||
test result: ok. 145 passed; 0 failed; 0 ignored; 0 measured;
|
||||
0 filtered out
|
||||
```
|
||||
|
||||
1 new test added (144 → 145):
|
||||
|
||||
* `register_unimplemented_export_marks_set_membership` — verifies the
|
||||
new `register_unimplemented_export` API both installs the export
|
||||
func (so `call_export` finds and runs the stub) AND inserts the
|
||||
`(module, ord)` pair into `unimplemented_exports` (so the Phase A
|
||||
emitter guard suppresses events). Cross-checks the negative case:
|
||||
a normal `register_export` does NOT mark unimplemented.
|
||||
|
||||
Full workspace test suite (`cargo test --release --workspace`):
|
||||
no regressions.
|
||||
|
||||
## Summary
|
||||
|
||||
All 6 gates pass. Phase A main matched prefix grew from 102132 to
|
||||
102158 (+26 events). One class-E (Phase A coverage gap) engine bug
|
||||
fixed: ours's emitter injected 3 spurious events
|
||||
(`import.call`/`kernel.call`/`kernel.return`) for
|
||||
`IoDismountVolumeByFileHandle` because canary's syscall-thunk path
|
||||
for table-entry-only exports never reaches `Trampoline` and emits
|
||||
nothing. New `register_unimplemented_export` API in `state.rs` lets
|
||||
us mark such exports for Phase A suppression while keeping their
|
||||
stub body execution intact. Cvar-OFF inert.
|
||||
|
||||
Diff-tool unchanged. Canary unchanged.
|
||||
|
||||
Next divergence: **XamTaskCloseHandle return value at
|
||||
tid_event_idx=102158** (canary=1, ours=0 — value divergence). Phase
|
||||
C+7 target.
|
||||
Reference in New Issue
Block a user