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:
131
audit-runs/phase-c10-NtQueryFullAttributesFile/diff-report.md
Normal file
131
audit-runs/phase-c10-NtQueryFullAttributesFile/diff-report.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Phase A diff report
|
||||
|
||||
**This report is the output of Phase A's diff harness. Divergences
|
||||
shown here are INPUT for Phase B (first-divergence localization),
|
||||
not findings of Phase A.** Phase A's job is to make the harness
|
||||
itself correct, not to analyze what it surfaces.
|
||||
|
||||
## Summary
|
||||
|
||||
| canary_tid | ours_tid | matched | canary_total | ours_total | first_divergence_at |
|
||||
|---|---|---|---|---|---|
|
||||
| 4 | 11 | 9 | 27668 | 9 | — |
|
||||
| 6 | 1 | 102404 | 315020 | 108471 | 102404 |
|
||||
| 7 | 2 | 29 | 29 | 30 | — |
|
||||
| 12 | 7 | 2 | 3404 | 3 | 2 |
|
||||
| 14 | 9 | 39 | 667692 | 75 | 39 |
|
||||
| 15 | 10 | 15 | 417763 | 15 | — |
|
||||
|
||||
## canary_tid=4 → ours_tid=11
|
||||
|
||||
No divergence within the 9 compared events (canary has 27668, ours has 9).
|
||||
|
||||
## canary_tid=6 → ours_tid=1
|
||||
|
||||
First divergence at `tid_event_idx=102404`: payload.return_value: canary=0 ours=3221225524
|
||||
|
||||
**Pre-context (last 5 matching events):**
|
||||
```
|
||||
canary: [102399] import.call RtlInitAnsiString
|
||||
ours: [102399] import.call RtlInitAnsiString
|
||||
canary: [102400] kernel.call RtlInitAnsiString
|
||||
ours: [102400] kernel.call RtlInitAnsiString
|
||||
canary: [102401] kernel.return RtlInitAnsiString
|
||||
ours: [102401] kernel.return RtlInitAnsiString
|
||||
canary: [102402] import.call NtQueryFullAttributesFile
|
||||
ours: [102402] import.call NtQueryFullAttributesFile
|
||||
canary: [102403] kernel.call NtQueryFullAttributesFile
|
||||
ours: [102403] kernel.call NtQueryFullAttributesFile
|
||||
```
|
||||
|
||||
**Divergent event:**
|
||||
```
|
||||
canary: [102404] kernel.return NtQueryFullAttributesFile
|
||||
ours: [102404] kernel.return NtQueryFullAttributesFile
|
||||
```
|
||||
|
||||
**Next event after the divergence (if any):**
|
||||
```
|
||||
canary: [102405] import.call RtlEnterCriticalSection
|
||||
ours: [102405] import.call RtlNtStatusToDosError
|
||||
```
|
||||
|
||||
**Raw events (JSON):**
|
||||
```json
|
||||
{"deterministic": true, "engine": "canary", "guest_cycle": 0, "host_ns": 773917700, "kind": "kernel.return", "payload": {"name": "NtQueryFullAttributesFile", "return_value": 0, "side_effects": [], "status": "0x00000000"}, "schema_version": 1, "tid": 6, "tid_event_idx": 102404}
|
||||
{"deterministic": true, "engine": "ours", "guest_cycle": 5391947, "host_ns": 470401201, "kind": "kernel.return", "payload": {"name": "NtQueryFullAttributesFile", "return_value": 3221225524, "side_effects": [], "status": "0xc0000034"}, "schema_version": 1, "tid": 1, "tid_event_idx": 102404}
|
||||
```
|
||||
|
||||
## canary_tid=7 → ours_tid=2
|
||||
|
||||
No divergence within the 29 compared events (canary has 29, ours has 30).
|
||||
|
||||
## canary_tid=12 → ours_tid=7
|
||||
|
||||
First divergence at `tid_event_idx=2`: payload.return_value: canary=258 ours=0
|
||||
|
||||
**Pre-context (last 5 matching events):**
|
||||
```
|
||||
canary: [0] import.call KeWaitForSingleObject
|
||||
ours: [0] import.call KeWaitForSingleObject
|
||||
canary: [1] kernel.call KeWaitForSingleObject
|
||||
ours: [1] kernel.call KeWaitForSingleObject
|
||||
```
|
||||
|
||||
**Divergent event:**
|
||||
```
|
||||
canary: [2] kernel.return KeWaitForSingleObject
|
||||
ours: [2] kernel.return KeWaitForSingleObject
|
||||
```
|
||||
|
||||
**Next event after the divergence (if any):**
|
||||
```
|
||||
canary: [3] import.call RtlEnterCriticalSection
|
||||
ours: <end of stream>
|
||||
```
|
||||
|
||||
**Raw events (JSON):**
|
||||
```json
|
||||
{"deterministic": true, "engine": "canary", "guest_cycle": 0, "host_ns": 922327400, "kind": "kernel.return", "payload": {"name": "KeWaitForSingleObject", "return_value": 258, "side_effects": [], "status": "0x00000102"}, "schema_version": 1, "tid": 12, "tid_event_idx": 2}
|
||||
{"deterministic": true, "engine": "ours", "guest_cycle": 30, "host_ns": 495749641, "kind": "kernel.return", "payload": {"name": "KeWaitForSingleObject", "return_value": 0, "side_effects": [], "status": "0x00000000"}, "schema_version": 1, "tid": 7, "tid_event_idx": 2}
|
||||
```
|
||||
|
||||
## canary_tid=14 → ours_tid=9
|
||||
|
||||
First divergence at `tid_event_idx=39`: payload.ord: canary=503 ours=293
|
||||
|
||||
**Pre-context (last 5 matching events):**
|
||||
```
|
||||
canary: [34] kernel.call KeReleaseSpinLockFromRaisedIrql
|
||||
ours: [34] kernel.call KeReleaseSpinLockFromRaisedIrql
|
||||
canary: [35] kernel.return KeReleaseSpinLockFromRaisedIrql
|
||||
ours: [35] kernel.return KeReleaseSpinLockFromRaisedIrql
|
||||
canary: [36] import.call KfLowerIrql
|
||||
ours: [36] import.call KfLowerIrql
|
||||
canary: [37] kernel.call KfLowerIrql
|
||||
ours: [37] kernel.call KfLowerIrql
|
||||
canary: [38] kernel.return KfLowerIrql
|
||||
ours: [38] kernel.return KfLowerIrql
|
||||
```
|
||||
|
||||
**Divergent event:**
|
||||
```
|
||||
canary: [39] import.call XAudioGetVoiceCategoryVolumeChangeMask
|
||||
ours: [39] import.call RtlEnterCriticalSection
|
||||
```
|
||||
|
||||
**Next event after the divergence (if any):**
|
||||
```
|
||||
canary: [40] kernel.call XAudioGetVoiceCategoryVolumeChangeMask
|
||||
ours: [40] kernel.call RtlEnterCriticalSection
|
||||
```
|
||||
|
||||
**Raw events (JSON):**
|
||||
```json
|
||||
{"deterministic": true, "engine": "canary", "guest_cycle": 0, "host_ns": 1125054700, "kind": "import.call", "payload": {"module": "xboxkrnl.exe", "name": "XAudioGetVoiceCategoryVolumeChangeMask", "ord": 503}, "schema_version": 1, "tid": 14, "tid_event_idx": 39}
|
||||
{"deterministic": true, "engine": "ours", "guest_cycle": 417, "host_ns": 1686986655, "kind": "import.call", "payload": {"module": "xboxkrnl.exe", "name": "RtlEnterCriticalSection", "ord": 293}, "schema_version": 1, "tid": 9, "tid_event_idx": 39}
|
||||
```
|
||||
|
||||
## canary_tid=15 → ours_tid=10
|
||||
|
||||
No divergence within the 15 compared events (canary has 417763, ours has 15).
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000002,
|
||||
"imports": 40465,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000002,
|
||||
"imports": 40465,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000002,
|
||||
"imports": 40465,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
212
audit-runs/phase-c10-NtQueryFullAttributesFile/escalation.md
Normal file
212
audit-runs/phase-c10-NtQueryFullAttributesFile/escalation.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# Phase C+10 — NtQueryFullAttributesFile — ESCALATION
|
||||
|
||||
## Outcome
|
||||
|
||||
**Phase 1 (emitter extension) — LANDED**.
|
||||
**Phase 4 fix (cache-state seeding) — ESCALATED**, deferred to a
|
||||
dedicated cache-subsystem session.
|
||||
|
||||
The Phase A emitter now resolves OBJECT_ATTRIBUTES path arguments on
|
||||
both engines (cvar-gated, default-off, behaviorally inert when off).
|
||||
That permanent infrastructure win surfaces the divergence string for
|
||||
this and every future file-IO divergence.
|
||||
|
||||
The actual cache-seeding fix needed to advance main matched-prefix
|
||||
past 102,404 is out of scope per the user's escalation criteria.
|
||||
|
||||
## Captured framing (post-extension)
|
||||
|
||||
Both engines now log the resolved path at `kernel.call.args_resolved`:
|
||||
|
||||
```
|
||||
canary[6][102403]: NtQueryFullAttributesFile args_resolved.path = "cache:\\d4ea4615\\e\\46ee8ca"
|
||||
ours [1][102403]: NtQueryFullAttributesFile args_resolved.path = "cache:\\d4ea4615\\e\\46ee8ca"
|
||||
|
||||
canary[6][102404]: kernel.return return_value = 0 (STATUS_SUCCESS)
|
||||
ours [1][102404]: kernel.return return_value = 0xC0000034 (STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
```
|
||||
|
||||
Both engines query the **same path**. Canary returns SUCCESS because
|
||||
its cache directory (`/home/fabi/.local/share/Xenia/cache/`) is
|
||||
**pre-populated** with 23 files (~5 MB) accumulated over prior
|
||||
Sylpheed boots. Ours's cache directory is fresh-wiped per AUDIT-038.
|
||||
|
||||
After this query, canary follows up with `NtCreateFile` for the same
|
||||
path (idx 102481) — it actually reads the cached data. So just lying
|
||||
SUCCESS without backing bytes would only push the divergence ~78
|
||||
events forward.
|
||||
|
||||
## Classification (per plan Phase 4)
|
||||
|
||||
**(A) Missing file — narrowly true (this single cache entry), but**
|
||||
**(D) Subsystem-required — actual scope**.
|
||||
|
||||
Choices considered:
|
||||
|
||||
1. **Plant a single file**: would only push the divergence to the
|
||||
next cache-existence query (16+ distinct hashes in
|
||||
`cache:\<HASH1>\<X>\<HASH2>` form). 23 files in canary's cache,
|
||||
most of them follow this pattern. After each plant the next
|
||||
query still misses.
|
||||
|
||||
2. **Seed ours's cache from canary's**: 23 files, ~5 MB. Mechanically
|
||||
easy (~30 LOC `copy_dir_all`) but violates AUDIT-038's no-oracle-
|
||||
state line AND AUDIT-053's documented warm-start regression
|
||||
(Sylpheed's `cache:\*.tmp` journal-style writes append per boot,
|
||||
making a naive persistent seed self-inconsistent after the second
|
||||
boot — `runtime_error` throws from version-check on reload).
|
||||
|
||||
3. **Lie SUCCESS on cache: existence + lie SUCCESS on subsequent
|
||||
NtCreateFile + return zero-byte file**: changes Nt semantics
|
||||
game-wide, likely breaks any read that expects valid content.
|
||||
|
||||
4. **Implement the game's cache-generation logic**: that's the
|
||||
shader/PSO/material cache build subsystem — multi-hundred-LOC
|
||||
generative subsystem, not in scope.
|
||||
|
||||
The user's escalation criteria explicitly call out
|
||||
"cache-population infrastructure" as ESCALATION. Choices 2-4 fit
|
||||
that. Choice 1 doesn't solve the problem.
|
||||
|
||||
## What was landed (Phase 1 only)
|
||||
|
||||
Permanent emitter extension on both engines, schema-v1-compatible
|
||||
(`args_resolved` was already part of v1, this just populates it for
|
||||
OBJECT_ATTRIBUTES*-taking exports).
|
||||
|
||||
### Ours side (~50 LOC additive)
|
||||
|
||||
- `xenia-rs/crates/xenia-kernel/src/event_log.rs`:
|
||||
- New `emit_kernel_call_with_path(tid, cycle, name, Option<&str>)`
|
||||
that mirrors `emit_kernel_call` but adds
|
||||
`args_resolved:{"path":"..."}` when the path is non-empty.
|
||||
Degrades to the existing empty-object form otherwise so output
|
||||
is byte-identical to pre-extension when the path is null.
|
||||
|
||||
- `xenia-rs/crates/xenia-kernel/src/path.rs`:
|
||||
- New `object_attributes_raw_name(mem, ptr) -> Option<String>`
|
||||
that returns the **raw** trimmed path (no prefix-strip, no
|
||||
case-fold). The emitter uses raw form so the diff surfaces
|
||||
upstream differences (e.g. if one engine called with one prefix
|
||||
and the other with a different prefix), not just post-normalize
|
||||
differences.
|
||||
|
||||
- `xenia-rs/crates/xenia-kernel/src/state.rs`:
|
||||
- In `call_export`, when `phase_a_on` and `name` matches one of
|
||||
`{NtCreateFile, NtOpenFile, NtQueryFullAttributesFile,
|
||||
NtOpenSymbolicLinkObject}`, resolve OBJECT_ATTRIBUTES* from the
|
||||
appropriate gpr position (verified against canary's
|
||||
xboxkrnl_io.cc signatures) and call
|
||||
`emit_kernel_call_with_path`. Otherwise call the legacy
|
||||
`emit_kernel_call`.
|
||||
|
||||
### Canary side (~80 LOC additive)
|
||||
|
||||
- `xenia-canary/src/xenia/kernel/event_log.h`:
|
||||
- New `EmitKernelCallWithPath(name, path)` mirroring ours.
|
||||
|
||||
- `xenia-canary/src/xenia/kernel/event_log.cc`:
|
||||
- Implementation of `EmitKernelCallWithPath`.
|
||||
- New `phase_a_bridge::EmitImportAndCallWithCtx(module, ord, name,
|
||||
ppc_context)` that dispatches by `name` to read OBJECT_ATTRIBUTES
|
||||
from the PPCContext gpr and call the path-bearing form. Falls
|
||||
back to the legacy form when name doesn't match.
|
||||
- Helper `ReadObjectAttributesRawName(obj_attrs_ptr)` that mirrors
|
||||
ours's `object_attributes_raw_name` semantically (raw trimmed,
|
||||
no normalization).
|
||||
|
||||
- `xenia-canary/src/xenia/kernel/util/shim_utils.h`:
|
||||
- Both trampolines (X::Trampoline / Y::Trampoline) switched from
|
||||
`EmitImportAndCall(...)` to `EmitImportAndCallWithCtx(...,
|
||||
ppc_context)`. PPCContext is already in scope at that call site
|
||||
(it's the first argument the trampoline receives).
|
||||
|
||||
Total: ~80 LOC each side. Both behaviorally inert when cvar OFF.
|
||||
|
||||
## Gates (Phase 1 extension only — all pass)
|
||||
|
||||
| # | gate | result |
|
||||
|---|---|---|
|
||||
| 1 | cvar-OFF determinism 50M (3 runs) | PASS — all 3 = `b8fa0e0460359a4f660adb7605e053de` (matches C+9 baseline, unchanged) |
|
||||
| 2 | Phase B `image_loaded_sha256` | PASS — `ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18` (matches baseline) |
|
||||
| 3 | Phase A main matched-prefix | UNCHANGED — 102404 (extension was framing-only; no fix landed; no advance expected) |
|
||||
| 4 | Both engines build clean | PASS |
|
||||
| 5 | Phase A emitter det fields (2 runs) | PASS — both = `7489e90ef4c9be629af8c9fabb1cbdd7` (new; replaces C+9's `0b299c37…` because the new args_resolved.path field is part of the det signature) |
|
||||
| 6 | Unit tests | PASS — 165 → 165 (no new, no regressions) |
|
||||
|
||||
## Schema status
|
||||
|
||||
The args_resolved field is part of schema-v1 already; this Phase only
|
||||
**populates** it for a subset of exports. No schema version bump.
|
||||
|
||||
The schema-v1 example (`schema-v1.md:112`) shows exactly the form we
|
||||
emit. We are now compliant with the documented schema for path-bearing
|
||||
exports rather than emitting an empty stub.
|
||||
|
||||
## Cascade prediction (resolution / next steps)
|
||||
|
||||
| stage | predicted | outcome |
|
||||
|---|---|---|
|
||||
| A=extend emitter cleanly | ~80% | LANDED |
|
||||
| B=capture path string both engines | ~85% | LANDED — `cache:\d4ea4615\e\46ee8ca` matched both engines |
|
||||
| C=classify root cause | ~75% | DONE — Class D (subsystem-required) |
|
||||
| D=land fix in scope | ~55% | **ESCALATED** — fix is choice 2-4 above |
|
||||
| E=main chain advances past 102404 | ~50% | NOT THIS SESSION |
|
||||
|
||||
## Reading-error class
|
||||
|
||||
NO new class. Existing classes #15 / ζ (VFS layout aliasing,
|
||||
AUDIT-053) and AUDIT-038 (no oracle state) are re-affirmed:
|
||||
|
||||
* Class #15 ζ (AUDIT-053): persistent cache + journal `.tmp` writes
|
||||
create a warm-start regression.
|
||||
* AUDIT-038 line: oracle state is forbidden in default boot.
|
||||
|
||||
Both rules together make the cache-seeding fix subsystem-tier, not
|
||||
single-fix-tier.
|
||||
|
||||
## Handoff to dedicated cache-subsystem session
|
||||
|
||||
The next session targeting this divergence should:
|
||||
|
||||
1. **Decide cache-state strategy**:
|
||||
- (a) Implement Sylpheed's cache-generation logic so ours builds
|
||||
its own cache from scratch (matches canary's own bootstrap
|
||||
experience — but multi-hundred-LOC).
|
||||
- (b) Seed-once-then-persist: copy canary's cache into ours's
|
||||
cache_root behind a new cvar `--cache-seed-from=<path>`, then
|
||||
enable persistence. AUDIT-053's warm-start regression must be
|
||||
re-tested with AUDIT-054's FILE_DIRECTORY_FILE fix in tree
|
||||
(it landed AFTER 053's regression was observed).
|
||||
- (c) Hybrid: synthesize a stub success at NtQueryFullAttributesFile
|
||||
for known-good cache hashes, then synthesize NtCreateFile/Read
|
||||
responses with bytes captured from canary's cache files. Closest
|
||||
to a "single missing file plant" but for 23 files.
|
||||
|
||||
2. **Re-validate after the fix** that the warm-start regression
|
||||
identified in AUDIT-053 doesn't recur (AUDIT-054 may have fixed
|
||||
it; needs explicit re-test).
|
||||
|
||||
3. **Expect cascading Phase A divergences**: each cache hash the
|
||||
game looks up in turn — the divergence at 102,404 is only the
|
||||
FIRST. After cache:\d4ea4615 is resolved, the game queries
|
||||
cache:\69d8e45c (idx 103810 already visible in ours.jsonl) and
|
||||
so on through 16+ distinct hashes per AUDIT-052.
|
||||
|
||||
## Files in this audit run
|
||||
|
||||
| file | content |
|
||||
|---|---|
|
||||
| `escalation.md` | this file |
|
||||
| `investigation.md` | Phase 1-4 walkthrough |
|
||||
| `re-validation.md` | gate results (Phase 1 extension only) |
|
||||
| `ours.jsonl`, `ours-determ.jsonl`, `canary.jsonl` | Phase A logs with new args_resolved field |
|
||||
| `diff-report.md` | re-run with path field populated |
|
||||
| `snap/ours/` | Phase B snapshot (unchanged from C+9) |
|
||||
| `digest-cvaroff-{1,2,3}.json` | 3× determinism (all = C+9 baseline) |
|
||||
|
||||
## Next target
|
||||
|
||||
**Same idx 102,404 NtQueryFullAttributesFile**, but in a dedicated
|
||||
cache-subsystem session. Path framing is now captured for the next
|
||||
investigator's first read.
|
||||
236
audit-runs/phase-c10-NtQueryFullAttributesFile/investigation.md
Normal file
236
audit-runs/phase-c10-NtQueryFullAttributesFile/investigation.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# Phase C+10 — NtQueryFullAttributesFile — Investigation
|
||||
|
||||
## Phase 1: Emitter extension (LANDED)
|
||||
|
||||
### Problem
|
||||
|
||||
C+9 left the divergence with no resolved path string:
|
||||
|
||||
```
|
||||
canary[6][102404] kernel.return NtQueryFullAttributesFile return_value=0
|
||||
ours [1][102404] kernel.return NtQueryFullAttributesFile return_value=0xC0000034
|
||||
```
|
||||
|
||||
`payload.args` and `payload.args_resolved` were both empty objects.
|
||||
We had no way to identify WHICH file the engine was querying.
|
||||
|
||||
### Shape of the fix
|
||||
|
||||
Schema v1 already declares `args_resolved` as a free-form object
|
||||
attached to `kernel.call` (schema-v1.md:108-117), and the existing
|
||||
example explicitly shows `{"path":"..."}`. The emitter just wasn't
|
||||
populating it. Extension is pure schema-v1 compliance, no version
|
||||
bump.
|
||||
|
||||
#### Ours-side (event_log.rs / path.rs / state.rs)
|
||||
|
||||
- Added `event_log::emit_kernel_call_with_path(tid, cycle, name,
|
||||
Option<&str>)` — same byte format as `emit_kernel_call`, but when
|
||||
`path` is `Some(non_empty)` emits `args_resolved:{"path":"..."}`.
|
||||
When `None` or empty, degrades to the existing
|
||||
`args_resolved:{}` form so unrelated exports' output is
|
||||
byte-identical to pre-extension.
|
||||
|
||||
- Added `path::object_attributes_raw_name(mem, ptr) -> Option<String>`
|
||||
— returns the RAW path string (trimmed of whitespace, NO
|
||||
prefix-strip / no case-fold) so the diff surfaces upstream
|
||||
prefix-form differences instead of masking them via normalization.
|
||||
Pre-existing `object_attributes_to_vfs_path` (which DOES normalize)
|
||||
is kept as-is for VFS lookup callers; emitter uses the new raw
|
||||
helper.
|
||||
|
||||
- `state.rs::call_export`, inside the `phase_a_on` guarded block:
|
||||
new `match name` resolves OBJECT_ATTRIBUTES* from the right gpr
|
||||
position. Argument positions verified against canary's
|
||||
`xboxkrnl/xboxkrnl_io.cc` signatures:
|
||||
- `NtQueryFullAttributesFile` → r3 = obj_attrs
|
||||
- `NtOpenSymbolicLinkObject` → r4 = obj_attrs
|
||||
- `NtCreateFile`, `NtOpenFile` → r5 = obj_attrs
|
||||
Then calls `emit_kernel_call_with_path(..., resolved.as_deref())`
|
||||
instead of `emit_kernel_call(...)`. All other exports fall through
|
||||
to `None` and the legacy form.
|
||||
|
||||
#### Canary-side (event_log.h / event_log.cc / util/shim_utils.h)
|
||||
|
||||
- `event_log.h`: declared `EmitKernelCallWithPath(name, path)`.
|
||||
- `event_log.cc`: implemented same as ours (degrades to legacy form
|
||||
for empty path).
|
||||
- `event_log.cc::phase_a_bridge::EmitImportAndCallWithCtx(module,
|
||||
ord, name, ppc_context)` — new bridge function. PPCContext is
|
||||
passed as `void*` to keep the header transitive include footprint
|
||||
small (the bridge cc reinterprets to PPCContext* internally).
|
||||
Inside the bridge, helper `ReadObjectAttributesRawName(ptr)` reads
|
||||
the X_OBJECT_ATTRIBUTES.name_ptr, then the X_ANSI_STRING bytes
|
||||
directly out of guest memory (no util::TranslateAnsiPath
|
||||
normalization). Trims whitespace + trailing NULs to match ours's
|
||||
semantics byte-for-byte.
|
||||
- `util/shim_utils.h`: both export trampolines (X::Trampoline /
|
||||
Y::Trampoline) switched the `phase_a_bridge::EmitImportAndCall`
|
||||
call to `phase_a_bridge::EmitImportAndCallWithCtx`, passing the
|
||||
existing `ppc_context` argument that's already in scope. The
|
||||
legacy `EmitImportAndCall` stays declared and defined for any
|
||||
future callers that don't have a PPCContext.
|
||||
|
||||
### Verification
|
||||
|
||||
- Build both engines clean.
|
||||
- Determinism 3x: digest md5 = `b8fa0e0460359a4f660adb7605e053de`
|
||||
(identical to C+9 baseline — extension is cvar-OFF zero-cost).
|
||||
- Phase A emitter determinism 2x: det-fields md5 = `7489e90e…` byte
|
||||
identical. (Different from C+9's `0b299c37…` because the path
|
||||
field IS in the deterministic signature — but stable across runs.)
|
||||
|
||||
## Phase 2: Re-run + capture path string
|
||||
|
||||
After the extension, both engines emit the path at
|
||||
`kernel.call.args_resolved.path`:
|
||||
|
||||
```
|
||||
canary[6][102403] NtQueryFullAttributesFile path = "cache:\d4ea4615\e\46ee8ca"
|
||||
ours [1][102403] NtQueryFullAttributesFile path = "cache:\d4ea4615\e\46ee8ca"
|
||||
```
|
||||
|
||||
Both engines query the **same path**. No upstream divergence — the
|
||||
ANSI_STRING content matches byte-for-byte.
|
||||
|
||||
## Phase 3: Why does ours say NOT_FOUND?
|
||||
|
||||
### Trace through ours's `nt_query_full_attributes_file`
|
||||
|
||||
`exports.rs:1913-1990`:
|
||||
|
||||
1. Read OBJECT_ATTRIBUTES → path =
|
||||
`"cache:/d4ea4615/e/46ee8ca"` (after `normalize_path`).
|
||||
2. `state.resolve_cache_path(&path)` returns
|
||||
`Some(<temp_dir>/xenia-rs-cache-<pid>-0/d4ea4615/e/46ee8ca)`.
|
||||
3. `std::fs::metadata(host_path)` returns `Err(NotFound)`.
|
||||
4. Return `STATUS_OBJECT_NAME_NOT_FOUND` (`0xC0000034`).
|
||||
|
||||
The host path doesn't exist because ours's `init_cache_root`
|
||||
(`state.rs:499-510`) **clears** the cache directory on every boot
|
||||
(AUDIT-038 line: per-process tmpdir + full wipe so two consecutive
|
||||
runs see byte-identical initial state).
|
||||
|
||||
### Why does canary's NOT fail?
|
||||
|
||||
`xenia-canary/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc:474-513`:
|
||||
|
||||
1. Read OBJECT_ATTRIBUTES → target_path via TranslateAnsiPath.
|
||||
2. `kernel_state()->file_system()->ResolvePath(target_path)`.
|
||||
3. If `entry` found, populate file_info, return `X_STATUS_SUCCESS`.
|
||||
4. Else return `X_STATUS_NO_SUCH_FILE` (`0xC0000035`).
|
||||
|
||||
Canary returns 0 → entry was found. Canary's cache mount is at
|
||||
`/home/fabi/.local/share/Xenia/cache/` (a persistent host directory
|
||||
populated over prior boots).
|
||||
|
||||
### Verification of canary's cache state
|
||||
|
||||
```
|
||||
$ ls /home/fabi/.local/share/Xenia/cache/d4ea4615/e/
|
||||
-rw-rw-r-- 1 fabi fabi 400 May 11 21:01 46ee8ca
|
||||
```
|
||||
|
||||
Single 400-byte file. Total cache: 23 files, ~5 MB across 16
|
||||
distinct top-level hash directories.
|
||||
|
||||
### Sibling-cache observations
|
||||
|
||||
ours.jsonl shows the SAME `NtQueryFullAttributesFile` fires for
|
||||
multiple cache paths within the 50M window — all returning
|
||||
`0xC0000034`. Example: idx 103810 queries
|
||||
`cache:\69d8e45c\8\3421153`. So the divergence is not a single
|
||||
missing file but a class of 16+ missing hashes.
|
||||
|
||||
## Phase 4: Classification + scope decision
|
||||
|
||||
Per the plan, the classes are:
|
||||
|
||||
* **(A) Missing file** — a single plant fixes it (small).
|
||||
* **(B) Path-normalization bug** — string operation (small).
|
||||
* **(C) VFS mount missing** — add the mount (small-medium).
|
||||
* **(D) Subsystem-required** — STFS or similar — **ESCALATE**.
|
||||
* **(E) Upstream divergence** — walk back.
|
||||
|
||||
This is **NOT (B)** — both engines normalize identically (verified
|
||||
by matching args_resolved.path).
|
||||
|
||||
This is **NOT (E)** — upstream is bit-identical for 102,403 events.
|
||||
|
||||
This is **NOT (A)** for any single file — the game queries 16+
|
||||
distinct cache hashes; planting one only postpones the divergence.
|
||||
|
||||
This is **closest to a hybrid (C+D)**:
|
||||
|
||||
* **(C)-ish**: canary's cache MOUNT resolves to a populated host dir;
|
||||
ours's mount resolves to a wiped tmp dir.
|
||||
* **(D)-ish**: canary's cache is populated because it ran the game
|
||||
before and the game **built** the cache. To match canary's state
|
||||
on a fresh boot, we either:
|
||||
- implement the game's cache-build logic (subsystem),
|
||||
- copy canary's pre-built cache (oracle state — AUDIT-038
|
||||
violation),
|
||||
- or accept that ours runs cold and the divergence is a
|
||||
fundamental cold-vs-warm asymmetry.
|
||||
|
||||
### AUDIT-053 cross-check (warm-start regression risk)
|
||||
|
||||
Per AUDIT-053 memo:
|
||||
> Phase 2 permanent fix REVERTED — warm-start regression from VFS
|
||||
> layout aliasing: `open_cache_file` treats all `NtCreateFile` as
|
||||
> files, but `cache:\d4ea4615 disp=CREATE` is meant as a DIRECTORY.
|
||||
|
||||
AUDIT-054 fixed that specific aliasing (FILE_DIRECTORY_FILE bit
|
||||
threading). But there's still the AUDIT-053 secondary concern:
|
||||
Sylpheed's `cache:\<hash>.tmp` journal-style writes append on each
|
||||
boot — making naive persistence self-inconsistent across boots.
|
||||
|
||||
Whether AUDIT-054's fix fully unblocks persistence is **NOT
|
||||
RE-VERIFIED** in this session. Re-testing the AUDIT-053 regression
|
||||
under AUDIT-054's fix-in-tree is itself a follow-up.
|
||||
|
||||
### Scope per user direction
|
||||
|
||||
User said:
|
||||
> If the fix requires major VFS work, STFS subsystem
|
||||
> implementation, or cache-population infrastructure: ESCALATE.
|
||||
|
||||
Choices 2-4 from `escalation.md` all qualify as "cache-population
|
||||
infrastructure":
|
||||
* Choice 1 (single file plant) won't solve the problem (16+ hashes).
|
||||
* Choice 2 (seed from canary) is oracle state + warm-start regression
|
||||
risk per AUDIT-053.
|
||||
* Choice 3 (synthesize cache reads) is multi-export semantic-change.
|
||||
* Choice 4 (build cache from scratch) is a full subsystem.
|
||||
|
||||
**ESCALATION declared.** Phase 1 emitter extension landed as the
|
||||
session's permanent infrastructure contribution.
|
||||
|
||||
## Discipline check
|
||||
|
||||
* **Reading-error #28** (canary source-of-truth): verified canary's
|
||||
actual `NtQueryFullAttributesFile_entry` body
|
||||
(`xboxkrnl_io.cc:474-513`), did not assume.
|
||||
* **Reading-error #23** (downstream regression): no fix landed, so
|
||||
no regression risk. Emitter extension is cvar-OFF zero-cost.
|
||||
* **Escalation discipline**: triggered cleanly; explicit memo;
|
||||
contributing infrastructure (emitter path resolution) kept.
|
||||
* **Path encoding**: ANSI_STRING raw bytes captured; both engines
|
||||
agree byte-for-byte; no Unicode issues for the queried path.
|
||||
* **AUDIT-054 deferred-item**: not re-touched. Cache persistence
|
||||
remains opt-in via `XENIA_CACHE_PERSIST=1`. Default keeps the
|
||||
AUDIT-038 wipe behavior.
|
||||
* **`--mute=true`**: every canary run.
|
||||
* **Renamed binaries**: `xrs-c10` / `xc-c10.exe`.
|
||||
|
||||
## Confidence
|
||||
|
||||
* **Phase 1 emitter extension**: HIGH — schema-compliant, additive,
|
||||
cvar-OFF zero-cost verified via determinism.
|
||||
* **Phase 4 classification**: HIGH — three independent observations
|
||||
agree (canary cache populated, ours cache wiped, multiple hashes).
|
||||
* **Cascade prediction at 102,404**: cache fix lands only the
|
||||
FIRST in a series — next cache hash will be the next divergence.
|
||||
Likely net delta of several hundred to a few thousand matched
|
||||
events per cache slot resolved, until a non-cache divergence
|
||||
appears.
|
||||
106
audit-runs/phase-c10-NtQueryFullAttributesFile/re-validation.md
Normal file
106
audit-runs/phase-c10-NtQueryFullAttributesFile/re-validation.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Phase C+10 — NtQueryFullAttributesFile — Re-validation
|
||||
|
||||
Validation against the Phase 1 emitter extension (only landed work).
|
||||
No fix landed for the actual divergence (ESCALATED — see
|
||||
`escalation.md`).
|
||||
|
||||
## Gate matrix
|
||||
|
||||
| # | gate | result |
|
||||
|---|---|---|
|
||||
| 1 | cvar-OFF determinism 50M (3 runs) | PASS — all 3 = `b8fa0e0460359a4f660adb7605e053de` (UNCHANGED from C+9 baseline; extension is zero-cost when cvar OFF) |
|
||||
| 2 | Phase B `image_loaded_sha256` | PASS — `ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18` (matches baseline; XEX loader untouched) |
|
||||
| 3 | Phase A main matched-prefix | UNCHANGED — 102404 (no fix landed; matched-prefix advance NOT expected this session) |
|
||||
| 3b | tid=4 → 11 unchanged | PASS — 9 (no regression) |
|
||||
| 3c | tid=7 → 2 unchanged | PASS — 29 (no regression) |
|
||||
| 3d | tid=12 → 7 unchanged | PASS — 2 (no regression) |
|
||||
| 3e | tid=14 → 9 unchanged | PASS — 39 (no regression) |
|
||||
| 3f | tid=15 → 10 unchanged | PASS — 15 (no regression) |
|
||||
| 4 | Both engines build clean | PASS (1 unrelated `walk_committed_regions` dead-code warning, pre-existing C+9) |
|
||||
| 5 | Phase A emitter determinism (2 runs) | PASS — both = `7489e90ef4c9be629af8c9fabb1cbdd7` |
|
||||
| 6 | Unit tests | PASS — 165 → 165 (no new tests; no regressions) |
|
||||
|
||||
## Stable-digest comparison
|
||||
|
||||
| field | C+9 baseline | C+10 post-extension | delta |
|
||||
|---|---|---|---|
|
||||
| (all stable fields, 3 runs) | `b8fa0e0460359a4f660adb7605e053de` | `b8fa0e0460359a4f660adb7605e053de` | 0 |
|
||||
|
||||
Extension is purely emitter-side, cvar-gated default-off, behaviorally
|
||||
inert. Determinism unchanged.
|
||||
|
||||
## Phase A determinism
|
||||
|
||||
```
|
||||
ours.jsonl (run 1) det-fields md5: 7489e90ef4c9be629af8c9fabb1cbdd7
|
||||
ours-determ.jsonl (run 2) det-fields md5: 7489e90ef4c9be629af8c9fabb1cbdd7
|
||||
```
|
||||
|
||||
Byte-identical on deterministic fields. New `--phase-a` det baseline
|
||||
`7489e90e…` (replaces C+9's `0b299c37…`). The signature changed
|
||||
because the new `args_resolved.path` field IS part of the
|
||||
deterministic payload — but it's stable across runs (path string is
|
||||
read directly out of guest memory, fully deterministic for fixed
|
||||
input).
|
||||
|
||||
## Per-chain summary
|
||||
|
||||
| chain | C+9 baseline | C+10 (after emitter extension) | delta |
|
||||
|---|---|---|---|
|
||||
| canary tid=6 → ours tid=1 (main) | 102404 | 102404 | 0 (no fix landed) |
|
||||
| canary tid=4 → ours tid=11 | 9 | 9 | 0 |
|
||||
| canary tid=7 → ours tid=2 | 29 | 29 | 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 | 15 | 15 | 0 |
|
||||
|
||||
All chains unchanged. No regressions. No advances (as expected — no
|
||||
behavioral change to either engine).
|
||||
|
||||
## Confirmed framing (Phase 1 success)
|
||||
|
||||
The divergence path is now visible in the diff output:
|
||||
|
||||
```
|
||||
canary[6][102403] kernel.call NtQueryFullAttributesFile
|
||||
args_resolved.path = "cache:\d4ea4615\e\46ee8ca"
|
||||
ours [1][102403] kernel.call NtQueryFullAttributesFile
|
||||
args_resolved.path = "cache:\d4ea4615\e\46ee8ca"
|
||||
```
|
||||
|
||||
Both engines query the SAME path. Both successfully read the
|
||||
OBJECT_ATTRIBUTES.name_ptr. Divergence is purely in
|
||||
`vfs.stat`/`file_system().ResolvePath` outcome (canary's mount has
|
||||
the file; ours's wiped cache doesn't).
|
||||
|
||||
## Sources of truth for the path field
|
||||
|
||||
Both engines read directly out of guest memory at the same point in
|
||||
the dispatch sequence (right before the export handler runs). The
|
||||
resulting string is byte-identical when input is identical. This is
|
||||
verified by the byte-identical det-fields md5 across runs.
|
||||
|
||||
## Phase 6 status
|
||||
|
||||
Gates 1-2, 3b-3f, 4-6 all pass. Gate 3 main-prefix did NOT advance.
|
||||
This is because **no fix was landed** — Phase 4 ESCALATED.
|
||||
|
||||
The session's contribution is:
|
||||
* Permanent emitter extension on both engines (~80 LOC each).
|
||||
* Path framing captured for the divergence.
|
||||
* Classification + scope-decision memo in `escalation.md`.
|
||||
|
||||
## Next target
|
||||
|
||||
Same idx 102,404, but in a dedicated cache-subsystem session that
|
||||
can:
|
||||
|
||||
1. Re-test AUDIT-053's warm-start regression under AUDIT-054's
|
||||
FILE_DIRECTORY_FILE fix.
|
||||
2. Decide between cache-build subsystem vs cache-seed-from-canary vs
|
||||
stub-success.
|
||||
3. Land + re-validate the cache-state mechanism + run Phase A to
|
||||
measure the cascade.
|
||||
|
||||
The path framing landed in this session is the permanent input for
|
||||
that follow-up session.
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"build_id": "ours-phaseB",
|
||||
"cvars": {
|
||||
"phase_b_dump_section_content": false,
|
||||
"phase_b_snapshot_and_exit": false,
|
||||
"phase_b_snapshot_dir": "audit-runs/phase-c10-NtQueryFullAttributesFile/snap"
|
||||
},
|
||||
"deterministic_skip": [
|
||||
"host_ns_at_snapshot",
|
||||
"wall_clock_iso8601",
|
||||
"build_id",
|
||||
"iso_path",
|
||||
"cvars.phase_b_snapshot_dir"
|
||||
],
|
||||
"engine": "ours",
|
||||
"host_ns_at_snapshot": 0,
|
||||
"image_loaded_sha256": "ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18",
|
||||
"iso_path": "",
|
||||
"schema_version": 1,
|
||||
"wall_clock_iso8601": "epoch:0",
|
||||
"xex_entry_point": "0x824ab748",
|
||||
"xex_header_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"xex_image_base": "0x82000000",
|
||||
"xex_image_size": 9568256
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"cr": [
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0",
|
||||
"0x0"
|
||||
],
|
||||
"ctr": "0x0000000000000000",
|
||||
"deterministic_skip": [
|
||||
"hw_id"
|
||||
],
|
||||
"engine": "ours",
|
||||
"fpr": [
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000"
|
||||
],
|
||||
"fpscr": "0x00000000",
|
||||
"gpr": [
|
||||
"0x0000000000000000",
|
||||
"0x00000000700fff00",
|
||||
"0x0000000020000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x000000007fff0000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000",
|
||||
"0x0000000000000000"
|
||||
],
|
||||
"hw_id": 0,
|
||||
"lr": "0x00000000bcbcbcbc",
|
||||
"msr": "0x0000000000009030",
|
||||
"pc": "0x824ab748",
|
||||
"pcr_base": "0x7fff0000",
|
||||
"schema_version": 1,
|
||||
"stack_base": "0x00000000",
|
||||
"stack_limit": "0x00000000",
|
||||
"thread_id": 1,
|
||||
"tls_base": "0x00000000",
|
||||
"vr": [
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000",
|
||||
"00000000000000000000000000000000"
|
||||
],
|
||||
"vrsave": "0xffffffff",
|
||||
"vscr": "00000000000000000000000000010000",
|
||||
"xer": {
|
||||
"ca": 0,
|
||||
"ov": 0,
|
||||
"so": 0,
|
||||
"tbc": 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"deterministic_skip": [
|
||||
"raw_handle_id",
|
||||
"exports_registered_count"
|
||||
],
|
||||
"engine": "ours",
|
||||
"exports_registered_count": 199,
|
||||
"exports_registered_sample": [
|
||||
"xam.xex!NetDll_WSACleanup",
|
||||
"xam.xex!NetDll_WSAStartup",
|
||||
"xam.xex!XGetAVPack",
|
||||
"xam.xex!XGetGameRegion",
|
||||
"xam.xex!XGetLanguage",
|
||||
"xam.xex!XGetVideoMode",
|
||||
"xam.xex!XMsgInProcessCall",
|
||||
"xam.xex!XMsgStartIORequest",
|
||||
"xam.xex!XMsgStartIORequestEx",
|
||||
"xam.xex!XNotifyGetNext",
|
||||
"xam.xex!XNotifyPositionUI",
|
||||
"xam.xex!XamAlloc",
|
||||
"xam.xex!XamContentClose",
|
||||
"xam.xex!XamContentCreate",
|
||||
"xam.xex!XamContentCreateEnumerator",
|
||||
"xam.xex!XamContentDelete",
|
||||
"xam.xex!XamContentGetCreator",
|
||||
"xam.xex!XamContentGetDeviceData",
|
||||
"xam.xex!XamContentGetDeviceName",
|
||||
"xam.xex!XamContentGetDeviceState",
|
||||
"xam.xex!XamContentSetThumbnail",
|
||||
"xam.xex!XamEnableInactivityProcessing",
|
||||
"xam.xex!XamEnumerate",
|
||||
"xam.xex!XamFree",
|
||||
"xam.xex!XamGetExecutionId",
|
||||
"xam.xex!XamGetSystemVersion",
|
||||
"xam.xex!XamInputGetCapabilities",
|
||||
"xam.xex!XamInputGetKeystrokeEx",
|
||||
"xam.xex!XamInputGetState",
|
||||
"xam.xex!XamInputSetState",
|
||||
"xam.xex!XamLoaderLaunchTitle",
|
||||
"xam.xex!XamLoaderTerminateTitle"
|
||||
],
|
||||
"exports_registered_sha256": "bca7668a2a76ce1d1cc4dba8a862a2f16ec6ee3b2aab8a71d8d8bc0ccc89a097",
|
||||
"handle_name_table": [],
|
||||
"notification_listeners": [],
|
||||
"objects": [
|
||||
{
|
||||
"details": {
|
||||
"entry_pc": "0x824ab748",
|
||||
"exit_code": null,
|
||||
"hw_id": 0,
|
||||
"is_entry_thread": true,
|
||||
"thread_id": 1
|
||||
},
|
||||
"handle_semantic_id": "9879c5053fedb1d0",
|
||||
"name": null,
|
||||
"raw_handle_id": "0x00001000",
|
||||
"type": "Thread",
|
||||
"type_code": 5
|
||||
}
|
||||
],
|
||||
"schema_version": 1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"engine": "ours",
|
||||
"files": {
|
||||
"config.json": "6c758b063ac9da341cb35c7319c68e5ef74543d206c9afa8b7c15d00edd293aa",
|
||||
"cpu_state.json": "4e6df54ca1939d08854f3a52b49ed2c5ee0823d63cdecad8a7395203dac5443a",
|
||||
"kernel.json": "2db219d4ca8b0313e53be379b8fcf90ab13b99116e6fac5601f6bdefd1aa6900",
|
||||
"memory.json": "b96ae4daebfbdd314e574492c1e162f532fa4f89ff5c0d7c6c29743797089cf1",
|
||||
"vfs.json": "97bb2bda57266d8e0dd1da13309eab5ece43130ef378a0b682917d299e9dc4e1"
|
||||
},
|
||||
"schema_version": 1
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"committed_pages_total": 2594,
|
||||
"deterministic_skip": [
|
||||
"host_base_pointer"
|
||||
],
|
||||
"engine": "ours",
|
||||
"guest_address_space_bytes": 4294967296,
|
||||
"heaps": [
|
||||
{
|
||||
"base": "0x00000000",
|
||||
"name": "v00000000",
|
||||
"page_size": 4096,
|
||||
"page_state_histogram": {
|
||||
"committed": 0
|
||||
},
|
||||
"size": "0x40000000"
|
||||
},
|
||||
{
|
||||
"base": "0x40000000",
|
||||
"name": "v40000000",
|
||||
"page_size": 4096,
|
||||
"page_state_histogram": {
|
||||
"committed": 266
|
||||
},
|
||||
"size": "0x40000000"
|
||||
},
|
||||
{
|
||||
"base": "0x80000000",
|
||||
"name": "v80000000",
|
||||
"page_size": 4096,
|
||||
"page_state_histogram": {
|
||||
"committed": 2336
|
||||
},
|
||||
"size": "0x40000000"
|
||||
},
|
||||
{
|
||||
"base": "0x90000000",
|
||||
"name": "v90000000",
|
||||
"page_size": 4096,
|
||||
"page_state_histogram": {
|
||||
"committed": 0
|
||||
},
|
||||
"size": "0x40000000"
|
||||
}
|
||||
],
|
||||
"page_size": 4096,
|
||||
"regions": [
|
||||
{
|
||||
"byte_count": 1048576,
|
||||
"end": "0x70100000",
|
||||
"protect": 0,
|
||||
"section_kind": null,
|
||||
"sha256": "30e14955ebf1352266dc2ff8067e68104607e750abb9d3b36582b8af909fcb58",
|
||||
"start": "0x70000000"
|
||||
},
|
||||
{
|
||||
"byte_count": 4096,
|
||||
"end": "0x7ffe1000",
|
||||
"protect": 0,
|
||||
"section_kind": null,
|
||||
"sha256": "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7",
|
||||
"start": "0x7ffe0000"
|
||||
},
|
||||
{
|
||||
"byte_count": 4096,
|
||||
"end": "0x7fff1000",
|
||||
"protect": 0,
|
||||
"section_kind": null,
|
||||
"sha256": "e35cddaf9c210aed7505ec4cf1c599f58ac2b7ec25b0885db1ee49aba2db519a",
|
||||
"start": "0x7fff0000"
|
||||
},
|
||||
{
|
||||
"byte_count": 9568256,
|
||||
"end": "0x82920000",
|
||||
"protect": 0,
|
||||
"section_kind": null,
|
||||
"sha256": "ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18",
|
||||
"start": "0x82000000"
|
||||
}
|
||||
],
|
||||
"regions_walked": [],
|
||||
"schema_version": 1,
|
||||
"section_contents": null
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"cache_root_listing": [],
|
||||
"deterministic_skip": [
|
||||
"host_path_realpath"
|
||||
],
|
||||
"engine": "ours",
|
||||
"mounted_devices_observed_count": 1,
|
||||
"resolve_path_probes": [
|
||||
{
|
||||
"is_directory": true,
|
||||
"path": "\\Device\\Cdrom0",
|
||||
"resolved": true,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": true,
|
||||
"path": "\\Device\\Cdrom0\\dat",
|
||||
"resolved": true,
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"is_directory": null,
|
||||
"path": "\\Device\\Cdrom0\\dat\\movie",
|
||||
"resolved": false,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": null,
|
||||
"path": "\\Device\\Cdrom0\\dat\\movie\\opening.bik",
|
||||
"resolved": false,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": false,
|
||||
"path": "\\Device\\Cdrom0\\default.xex",
|
||||
"resolved": true,
|
||||
"size": 3497984
|
||||
},
|
||||
{
|
||||
"is_directory": null,
|
||||
"path": "\\Device\\HardDisk0\\Partition1",
|
||||
"resolved": false,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": true,
|
||||
"path": "cache:\\",
|
||||
"resolved": true,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": null,
|
||||
"path": "cache:\\nonexistent_probe",
|
||||
"resolved": false,
|
||||
"size": null
|
||||
},
|
||||
{
|
||||
"is_directory": true,
|
||||
"path": "game:\\dat",
|
||||
"resolved": true,
|
||||
"size": 4096
|
||||
},
|
||||
{
|
||||
"is_directory": false,
|
||||
"path": "game:\\default.xex",
|
||||
"resolved": true,
|
||||
"size": 3497984
|
||||
}
|
||||
],
|
||||
"schema_version": 1
|
||||
}
|
||||
Reference in New Issue
Block a user