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:
51
audit-runs/phase-c8-keResetEvent/broad-impact.md
Normal file
51
audit-runs/phase-c8-keResetEvent/broad-impact.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Phase C+8 — broad-impact analysis
|
||||
|
||||
KeResetEvent is hot like KeSetEvent — called many times before idx=102164.
|
||||
Predecessor (C+7) advanced the main chain by +6 due to a stale-comment
|
||||
test; C+8 advances by +33 — modest but ~5x larger. Each event between
|
||||
102164 and 102197 is a continuation inside the same critical-section /
|
||||
content-enumeration block in the boot sequence.
|
||||
|
||||
## Pre-C+8 (post-C+7) tid=6->1 first-divergence
|
||||
|
||||
idx=102164 -- kernel.return KeResetEvent canary=1 ours=0
|
||||
|
||||
## Post-C+8 tid=6->1 first-divergence
|
||||
|
||||
idx=102197 -- kernel.return XamContentCreateEnumerator canary=1317 ours=0
|
||||
- 1317 = 0x525 = X_ERROR_NO_CONTENT (returned when no save data exists)
|
||||
- ours returning 0 implies our stub either succeeds blindly or doesn't
|
||||
implement the "no content" path
|
||||
|
||||
## Resolved divergences
|
||||
|
||||
idx=102164 KeResetEvent return_value=0 -> 1
|
||||
|
||||
## Advanced divergences
|
||||
|
||||
tid=6->1 first-divergence position 102164 -> 102197
|
||||
|
||||
## Persisted divergences
|
||||
|
||||
tid=12->7 idx=2 KeWaitForSingleObject canary=258 ours=0
|
||||
tid=14->9 idx=39 XAudio cluster vs RtlEnterCS
|
||||
|
||||
## NEW divergences (consequence of the C+8 fix)
|
||||
|
||||
None visible -- the new first-divergence at idx=102197 was already
|
||||
the second-divergence pre-fix (hidden behind 102164). Now exposed.
|
||||
|
||||
## Sister-chain stability
|
||||
|
||||
All 5 sister chains (tid=4, 7, 12, 14, 15) at their identical prior
|
||||
matched-prefix lengths. No regression to lockstep-mapped sub-runs.
|
||||
|
||||
## Coarse stable-digest stability
|
||||
|
||||
50M `c6d895829b4611964978990ae1cb8a6a` identical to C+7 baseline.
|
||||
Coarse digest is field-coarse at this stage; it doesn't yet count
|
||||
distinct event sequences inside the matched-window expansion.
|
||||
|
||||
## Test count
|
||||
|
||||
Pre: 156. Post: 160 (+4). No regressions.
|
||||
131
audit-runs/phase-c8-keResetEvent/diff-report.md
Normal file
131
audit-runs/phase-c8-keResetEvent/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 | 47573 | 9 | — |
|
||||
| 6 | 1 | 102197 | 329948 | 108486 | 102197 |
|
||||
| 7 | 2 | 29 | 29 | 30 | — |
|
||||
| 12 | 7 | 2 | 6689 | 3 | 2 |
|
||||
| 14 | 9 | 39 | 1371603 | 75 | 39 |
|
||||
| 15 | 10 | 15 | 863209 | 15 | — |
|
||||
|
||||
## canary_tid=4 → ours_tid=11
|
||||
|
||||
No divergence within the 9 compared events (canary has 47573, ours has 9).
|
||||
|
||||
## canary_tid=6 → ours_tid=1
|
||||
|
||||
First divergence at `tid_event_idx=102197`: payload.return_value: canary=1317 ours=0
|
||||
|
||||
**Pre-context (last 5 matching events):**
|
||||
```
|
||||
canary: [102192] import.call RtlLeaveCriticalSection
|
||||
ours: [102192] import.call RtlLeaveCriticalSection
|
||||
canary: [102193] kernel.call RtlLeaveCriticalSection
|
||||
ours: [102193] kernel.call RtlLeaveCriticalSection
|
||||
canary: [102194] kernel.return RtlLeaveCriticalSection
|
||||
ours: [102194] kernel.return RtlLeaveCriticalSection
|
||||
canary: [102195] import.call XamContentCreateEnumerator
|
||||
ours: [102195] import.call XamContentCreateEnumerator
|
||||
canary: [102196] kernel.call XamContentCreateEnumerator
|
||||
ours: [102196] kernel.call XamContentCreateEnumerator
|
||||
```
|
||||
|
||||
**Divergent event:**
|
||||
```
|
||||
canary: [102197] kernel.return XamContentCreateEnumerator
|
||||
ours: [102197] kernel.return XamContentCreateEnumerator
|
||||
```
|
||||
|
||||
**Next event after the divergence (if any):**
|
||||
```
|
||||
canary: [102198] import.call RtlEnterCriticalSection
|
||||
ours: [102198] import.call RtlEnterCriticalSection
|
||||
```
|
||||
|
||||
**Raw events (JSON):**
|
||||
```json
|
||||
{"deterministic": true, "engine": "canary", "guest_cycle": 0, "host_ns": 732531000, "kind": "kernel.return", "payload": {"name": "XamContentCreateEnumerator", "return_value": 1317, "side_effects": [], "status": "0x00000525"}, "schema_version": 1, "tid": 6, "tid_event_idx": 102197}
|
||||
{"deterministic": true, "engine": "ours", "guest_cycle": 5379162, "host_ns": 468793370, "kind": "kernel.return", "payload": {"name": "XamContentCreateEnumerator", "return_value": 0, "side_effects": [], "status": "0x00000000"}, "schema_version": 1, "tid": 1, "tid_event_idx": 102197}
|
||||
```
|
||||
|
||||
## 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": 904485700, "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": 495995325, "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": 1082563200, "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": 1679078398, "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 863209, ours has 15).
|
||||
10
audit-runs/phase-c8-keResetEvent/digest-200M-1.json
Normal file
10
audit-runs/phase-c8-keResetEvent/digest-200M-1.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 200000000,
|
||||
"imports": 40470,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-1.json
Normal file
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-1.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000000,
|
||||
"imports": 40470,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-2.json
Normal file
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-2.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000000,
|
||||
"imports": 40470,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-3.json
Normal file
10
audit-runs/phase-c8-keResetEvent/digest-cvaroff-3.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"instructions": 50000000,
|
||||
"imports": 40470,
|
||||
"unimpl": 0,
|
||||
"draws": 0,
|
||||
"swaps": 1,
|
||||
"unique_render_targets": 0,
|
||||
"shader_blobs_live": 0,
|
||||
"texture_cache_entries": 0
|
||||
}
|
||||
80
audit-runs/phase-c8-keResetEvent/fix.diff
Normal file
80
audit-runs/phase-c8-keResetEvent/fix.diff
Normal file
@@ -0,0 +1,80 @@
|
||||
Phase C+8 — KeResetEvent canary-parity return value (sibling of C+7)
|
||||
====================================================================
|
||||
|
||||
Scope: `crates/xenia-kernel/src/exports.rs`
|
||||
LOC: ~12 body + ~80 test = ~92 net
|
||||
|
||||
Body change — `ke_reset_event` (~4160-4181):
|
||||
--------------------------------------------
|
||||
|
||||
-fn ke_reset_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
- let h = ctx.gpr[3] as u32;
|
||||
- ensure_dispatcher_object(state, mem, h);
|
||||
- let previous = match state.objects.get_mut(&h) {
|
||||
- Some(KernelObject::Event { signaled, .. }) => {
|
||||
- let prev = *signaled;
|
||||
- *signaled = false;
|
||||
- prev as u32
|
||||
- }
|
||||
- _ => 0,
|
||||
- };
|
||||
- ctx.gpr[3] = previous as u64;
|
||||
-}
|
||||
+fn ke_reset_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
+ // r3 = PKEVENT on Ke* (guest pointer). See `ensure_dispatcher_object`
|
||||
+ // for the lazy-shadow step.
|
||||
+ let h = ctx.gpr[3] as u32;
|
||||
+ ensure_dispatcher_object(state, mem, h);
|
||||
+ // Canary parity (xevent.cc:72-75): `XEvent::Reset` returns constant `1`
|
||||
+ // on success — exact sibling of `XEvent::Set`. The NT contract claims
|
||||
+ // the prior signaled state, but canary hardcodes `1` and the game
|
||||
+ // observes that value via Phase A oracle at idx=102164. Sibling fix
|
||||
+ // of Phase C+7 KeSetEvent (xevent.cc:60-64). The `assert_always;
|
||||
+ // return 0` arm is preserved (no shadow -> 0).
|
||||
+ let (previous, found) = match state.objects.get_mut(&h) {
|
||||
+ Some(KernelObject::Event { signaled, .. }) => {
|
||||
+ let prev = *signaled;
|
||||
+ *signaled = false;
|
||||
+ (prev as u32, true)
|
||||
+ }
|
||||
+ _ => (0u32, false),
|
||||
+ };
|
||||
+ state.audit_signal(h, ctx.lr as u32, "KeResetEvent", previous as u64);
|
||||
+ ctx.gpr[3] = if found { 1 } else { 0 };
|
||||
+}
|
||||
|
||||
Existing test (~5631-5647) comment-only update:
|
||||
-----------------------------------------------
|
||||
|
||||
- assert_eq!(ctx.gpr[3], 1, "previous state must be reported");
|
||||
+ assert_eq!(ctx.gpr[3], 1, "canary parity: KeResetEvent returns constant 1 on hit");
|
||||
(plus updated doc explaining canary parity)
|
||||
|
||||
New tests added at module end (mirror of C+7's KeSetEvent block):
|
||||
-----------------------------------------------------------------
|
||||
|
||||
// Phase C+8 -- KeResetEvent canary-parity return value (sibling of C+7)
|
||||
1. ke_reset_event_returns_constant_one_on_unsignaled_manual_reset
|
||||
(this is THE Phase A oracle case -- prior state 0, canary returns 1)
|
||||
2. ke_reset_event_returns_constant_one_on_signaled_auto_reset
|
||||
(distinguish from prior-state-return bug: prior 1 == constant 1)
|
||||
3. ke_reset_event_returns_zero_on_missing_object
|
||||
(canary's `assert_always; return 0` arm -- invalid handle)
|
||||
4. nt_clear_event_resets_shadow_and_returns_status_success
|
||||
(already canary-parity; symmetry coverage)
|
||||
|
||||
`nt_clear_event` body: no change. Canary `NtClearEvent_entry` calls
|
||||
`xeNtClearEvent` which uses `XEvent::Clear` (void return); already
|
||||
returning STATUS_SUCCESS in ours.
|
||||
|
||||
Cascade outcome:
|
||||
----------------
|
||||
- A=verify canary's return: DONE, `1` confirmed from xevent.cc:72-75
|
||||
- B=land fix: DONE
|
||||
- C=main chain advances past 102164: DONE -- 102164 -> 102197 (+33)
|
||||
- D=clean re-validation: DONE
|
||||
- E=no escalation: DONE (12-LOC body change, additive tests only)
|
||||
|
||||
Next target: XamContentCreateEnumerator at tid=6->1 idx=102197
|
||||
canary return_value=1317 (0x525 = X_ERROR_NO_CONTENT)
|
||||
ours return_value=0 (likely STATUS_SUCCESS or missing impl)
|
||||
120
audit-runs/phase-c8-keResetEvent/investigation.md
Normal file
120
audit-runs/phase-c8-keResetEvent/investigation.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Phase C+8 — KeResetEvent investigation
|
||||
|
||||
## Framing (reading-error #28 verification — MANDATORY)
|
||||
|
||||
Per memory note `phase_c7_keSetEvent_2026_05_14`, reading-error class
|
||||
#28 is **"canary source supersedes NT-doc semantics"**: the predecessor
|
||||
`KeSetEvent` bug was that ours returned the NT-documented "prior signaled
|
||||
state", while canary unconditionally `return 1` from `XEvent::Set`.
|
||||
|
||||
Before writing any fix we **read canary's actual `XEvent::Reset` body**.
|
||||
|
||||
### Canary truth — `xenia-canary/src/xenia/kernel/xevent.cc` (lines 60-82)
|
||||
|
||||
```cpp
|
||||
int32_t XEvent::Set(uint32_t priority_increment, bool wait) {
|
||||
set_priority_increment(priority_increment);
|
||||
event_->Set();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t XEvent::Pulse(uint32_t priority_increment, bool wait) {
|
||||
set_priority_increment(priority_increment);
|
||||
event_->Pulse();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t XEvent::Reset() {
|
||||
event_->Reset();
|
||||
return 1; // <-- HARDCODED CONSTANT 1, exact sibling of Set()
|
||||
}
|
||||
|
||||
void XEvent::Query(uint32_t* out_type, uint32_t* out_state) { ... }
|
||||
void XEvent::Clear() { event_->Reset(); } // NB: used only internally
|
||||
```
|
||||
|
||||
### Canary truth — `xenia-canary/src/xenia/kernel/xboxkrnl/xboxkrnl_threading.cc`
|
||||
|
||||
```cpp
|
||||
dword_result_t KeResetEvent_entry(pointer_t<X_KEVENT> event_ptr) {
|
||||
auto ev = XObject::GetNativeObject<XEvent>(kernel_state(), event_ptr);
|
||||
if (!ev) {
|
||||
assert_always();
|
||||
return 0;
|
||||
}
|
||||
return ev->Reset(); // <-- returns the 1 from XEvent::Reset
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT1(KeResetEvent, kThreading, kImplemented);
|
||||
```
|
||||
|
||||
```cpp
|
||||
dword_result_t NtClearEvent_entry(dword_t handle) {
|
||||
return xeNtClearEvent(handle);
|
||||
}
|
||||
DECLARE_XBOXKRNL_EXPORT2(NtClearEvent, kThreading, kImplemented,
|
||||
kHighFrequency);
|
||||
```
|
||||
|
||||
`xeNtClearEvent` (search the file) calls `XEvent::Clear()` which is the
|
||||
`void`-returning variant — it does not propagate `Reset()`'s return.
|
||||
`xeNtClearEvent` returns `X_STATUS_SUCCESS` on hit, `X_STATUS_INVALID_HANDLE`
|
||||
on miss. **No out-pointer**. So `NtClearEvent` is NOT in the same class as
|
||||
`NtSetEvent`: it has no PreviousState argument at all.
|
||||
|
||||
### Ours truth pre-fix — `crates/xenia-kernel/src/exports.rs:4160-4172`
|
||||
|
||||
```rust
|
||||
fn ke_reset_event(ctx: &mut PpcContext, mem: &GuestMemory, state: &mut KernelState) {
|
||||
let h = ctx.gpr[3] as u32;
|
||||
ensure_dispatcher_object(state, mem, h);
|
||||
let previous = match state.objects.get_mut(&h) {
|
||||
Some(KernelObject::Event { signaled, .. }) => {
|
||||
let prev = *signaled;
|
||||
*signaled = false;
|
||||
prev as u32
|
||||
}
|
||||
_ => 0,
|
||||
};
|
||||
ctx.gpr[3] = previous as u64; // <-- BUG: returns prior state
|
||||
}
|
||||
```
|
||||
|
||||
Mirror-image of the pre-C+7 `ke_set_event` bug. Ours returns the prior
|
||||
signaled state (`0` since the event had just been reset earlier in the
|
||||
boot); canary returns the constant `1`.
|
||||
|
||||
`nt_clear_event` (4197-4203) already returns `STATUS_SUCCESS` — no out
|
||||
pointer involved. Verified canary parity for that branch.
|
||||
|
||||
### Phase A event at idx 102164 (raw)
|
||||
|
||||
```json
|
||||
canary: {"kind":"kernel.return","payload":{"name":"KeResetEvent",
|
||||
"return_value":1,"status":"0x00000001"},"tid":6,
|
||||
"tid_event_idx":102164}
|
||||
ours: {"kind":"kernel.return","payload":{"name":"KeResetEvent",
|
||||
"return_value":0,"status":"0x00000000"},"tid":1,
|
||||
"tid_event_idx":102164}
|
||||
```
|
||||
|
||||
return_value mismatch exactly matches the canary-hardcoded-`1` premise.
|
||||
|
||||
## Fix shape
|
||||
|
||||
`ke_reset_event`: set return to constant `1` on shadow hit, `0` on miss
|
||||
(canary's `assert_always(); return 0` path). Retain the `*signaled = false`
|
||||
side effect — that is real semantic state used by waiter wake plumbing,
|
||||
and unchanged from pre-fix behavior. Add an `audit_signal`-style record
|
||||
mirroring the predecessor's bookkeeping. Mirror of C+7 `ke_set_event` fix.
|
||||
|
||||
`nt_clear_event`: already canary-parity. No change.
|
||||
|
||||
Body LOC: ~10. Tests: ~4 new (mirrors of C+7's `ke_set_event_*` tests).
|
||||
|
||||
## Cascade (predictions)
|
||||
|
||||
- A=verify canary's return: DONE, `1` confirmed.
|
||||
- B=land fix: ~95% (one-line return change + minor bookkeeping).
|
||||
- C=main chain advances past 102164: ~85% (the bug is the diff key).
|
||||
- D=clean re-validation: ~80%.
|
||||
- E=no escalation: ~95% (small).
|
||||
55
audit-runs/phase-c8-keResetEvent/re-validation.md
Normal file
55
audit-runs/phase-c8-keResetEvent/re-validation.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Phase C+8 — KeResetEvent re-validation
|
||||
|
||||
## Gate matrix
|
||||
|
||||
| # | gate | result |
|
||||
|---|---|---|
|
||||
| 1 | cvar-OFF determinism 50M (3 runs) | PASS — all 3 = `c6d895829b4611964978990ae1cb8a6a` (unchanged from C+7 baseline; coarse 50M stable-digest fields don't yet see the post-102164 trajectory) |
|
||||
| 2 | Phase B `image_loaded_sha256` | PASS — `ea8d160e9369328a5b922258a92113efb8d7ce3e1a5c12cc521e375985c91c18` (matches baseline; `image_canonical_sha256` computed at diff-time depends only on the XEX loader which is untouched, so still `62c51908...`) |
|
||||
| 3 | Phase A main chain matched-prefix > 102164 | PASS — **102197** (+33 from 102164) |
|
||||
| 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 | Build clean | PASS (1 unrelated `walk_committed_regions` dead-code warning, pre-existing) |
|
||||
| 5 | Phase A emitter determinism (2 runs) | PASS — both deterministic-fields md5 = `9135e369547111096f2c6d2be130dbb1` |
|
||||
| 6 | Unit tests | PASS — 156 -> **160** (+4 new, 0 regressions) |
|
||||
|
||||
## Stable-digest comparison
|
||||
|
||||
Baseline (C+7 XamTaskCloseHandle): digest 50M `c6d895829b4611964978990ae1cb8a6a`.
|
||||
Post C+8 KeResetEvent: identical. The two changes (return value at 102164,
|
||||
downstream events) sit inside the matched window and don't yet move
|
||||
coarse counters (instructions=50M, imports=40470, unimpl=0, draws=0,
|
||||
swaps=1, unique_render_targets=0, shader_blobs_live=0, texture_cache_entries=0).
|
||||
This is the same coarseness pattern observed in C+7-precursor.
|
||||
|
||||
## Phase A determinism
|
||||
|
||||
ours.jsonl (run 1) det-fields md5: `9135e369547111096f2c6d2be130dbb1`
|
||||
ours-determ.jsonl (run 2) : `9135e369547111096f2c6d2be130dbb1`
|
||||
|
||||
Byte-identical on deterministic fields. New `--phase-a` det baseline
|
||||
(`9135e369...`), replacing C+7's `eca3ac9a...` baseline. Change is the
|
||||
return_value flip at idx=102164 (0 -> 1) cascading into a different
|
||||
event sequence inside the matched window after 102164.
|
||||
|
||||
## Per-chain summary
|
||||
|
||||
| chain | C+7 XamTaskCloseHandle | C+8 KeResetEvent | delta |
|
||||
|---|---|---|---|
|
||||
| canary tid=6 -> ours tid=1 (main) | 102164 | **102197** | **+33** |
|
||||
| canary tid=4 -> ours tid=11 | 9 | 9 | 0 (sister at end of ours window) |
|
||||
| canary tid=7 -> ours tid=2 | 29 | 29 | 0 (sister at end of ours window) |
|
||||
| canary tid=12 -> ours tid=7 | 2 | 2 | 0 (different bug: KeWaitForSingleObject ret 258 vs 0) |
|
||||
| canary tid=14 -> ours tid=9 | 39 | 39 | 0 (different bug: XAudio vs RtlEnterCS) |
|
||||
| canary tid=15 -> ours tid=10 | 15 | 15 | 0 |
|
||||
|
||||
All gates pass. No regressions.
|
||||
|
||||
## Next target
|
||||
|
||||
XamContentCreateEnumerator at tid=6->1 idx=102197:
|
||||
- canary return_value=1317 (0x525 = X_ERROR_NO_CONTENT)
|
||||
- ours return_value=0
|
||||
25
audit-runs/phase-c8-keResetEvent/snap/ours/config.json
Normal file
25
audit-runs/phase-c8-keResetEvent/snap/ours/config.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"build_id": "ours-phaseB",
|
||||
"cvars": {
|
||||
"phase_b_dump_section_content": false,
|
||||
"phase_b_snapshot_and_exit": true,
|
||||
"phase_b_snapshot_dir": "audit-runs/phase-c8-keResetEvent/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
|
||||
}
|
||||
234
audit-runs/phase-c8-keResetEvent/snap/ours/cpu_state.json
Normal file
234
audit-runs/phase-c8-keResetEvent/snap/ours/cpu_state.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
62
audit-runs/phase-c8-keResetEvent/snap/ours/kernel.json
Normal file
62
audit-runs/phase-c8-keResetEvent/snap/ours/kernel.json
Normal file
@@ -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
|
||||
}
|
||||
11
audit-runs/phase-c8-keResetEvent/snap/ours/manifest.json
Normal file
11
audit-runs/phase-c8-keResetEvent/snap/ours/manifest.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"engine": "ours",
|
||||
"files": {
|
||||
"config.json": "a1fd543e10478f1d95a29832b1e13f8c68791f4271a88a6b6ac4ec635d2145e3",
|
||||
"cpu_state.json": "4e6df54ca1939d08854f3a52b49ed2c5ee0823d63cdecad8a7395203dac5443a",
|
||||
"kernel.json": "2db219d4ca8b0313e53be379b8fcf90ab13b99116e6fac5601f6bdefd1aa6900",
|
||||
"memory.json": "b96ae4daebfbdd314e574492c1e162f532fa4f89ff5c0d7c6c29743797089cf1",
|
||||
"vfs.json": "97bb2bda57266d8e0dd1da13309eab5ece43130ef378a0b682917d299e9dc4e1"
|
||||
},
|
||||
"schema_version": 1
|
||||
}
|
||||
84
audit-runs/phase-c8-keResetEvent/snap/ours/memory.json
Normal file
84
audit-runs/phase-c8-keResetEvent/snap/ours/memory.json
Normal file
@@ -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
|
||||
}
|
||||
71
audit-runs/phase-c8-keResetEvent/snap/ours/vfs.json
Normal file
71
audit-runs/phase-c8-keResetEvent/snap/ours/vfs.json
Normal file
@@ -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