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:
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Capture canary tid=17 (the sub_821748F0 worker) FULL timeline.
|
||||
Lifetime: 1.9378s to 2.0918s = 154ms.
|
||||
4140 events total. Compare to ours's tid=13 which has only 80 events before wedge.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
from collections import Counter
|
||||
|
||||
INPUT = "/home/fabi/RE - Project Sylpheed/xenia-canary/build-cross/bin/Windows/Debug/canary-jitter-1.jsonl"
|
||||
OUTDIR = os.path.dirname(os.path.abspath(__file__))
|
||||
TARGET_TID = 17
|
||||
|
||||
T_LO = 1_900_000_000
|
||||
T_HI = 2_200_000_000
|
||||
|
||||
evts = []
|
||||
with open(INPUT, "r") as f:
|
||||
for line in f:
|
||||
if '"host_ns":' not in line:
|
||||
continue
|
||||
try:
|
||||
i = line.index('"host_ns":') + len('"host_ns":')
|
||||
j = i
|
||||
while j < len(line) and (line[j].isdigit() or line[j] == '-'):
|
||||
j += 1
|
||||
host_ns = int(line[i:j])
|
||||
except (ValueError, IndexError):
|
||||
continue
|
||||
if host_ns < T_LO:
|
||||
continue
|
||||
if host_ns >= T_HI:
|
||||
break
|
||||
if f'"tid":{TARGET_TID},' not in line:
|
||||
continue
|
||||
try:
|
||||
ev = json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if ev.get("tid") != TARGET_TID:
|
||||
continue
|
||||
evts.append(ev)
|
||||
|
||||
print(f"canary tid={TARGET_TID}: {len(evts)} events")
|
||||
if evts:
|
||||
print(f" first host_ns: {evts[0]['host_ns']/1e9:.4f}s")
|
||||
print(f" last host_ns: {evts[-1]['host_ns']/1e9:.4f}s")
|
||||
|
||||
# Top kernel calls.
|
||||
sum_calls = Counter()
|
||||
for ev in evts:
|
||||
if ev["kind"] == "kernel.call":
|
||||
sum_calls[ev["payload"].get("name", "?")] += 1
|
||||
|
||||
print(f"\n=== Top kernel.calls ({len(sum_calls)} unique) ===")
|
||||
for n, c in sum_calls.most_common(40):
|
||||
print(f" {c:5d} {n}")
|
||||
|
||||
# Save timeline.
|
||||
with open(os.path.join(OUTDIR, f"canary-tid{TARGET_TID}-worker-timeline.csv"), "w") as f:
|
||||
f.write("host_ns,tid_event_idx,kind,name,detail\n")
|
||||
for ev in evts:
|
||||
name = ev["payload"].get("name", "")
|
||||
detail = json.dumps(ev["payload"])[:400].replace('"', '""')
|
||||
f.write(f'{ev["host_ns"]},{ev["tid_event_idx"]},{ev["kind"]},{name},"{detail}"\n')
|
||||
|
||||
# Compare against ours tid=13.
|
||||
print("\n=== Now comparing ours tid=13 ===")
|
||||
OURS_INPUT = "/home/fabi/RE - Project Sylpheed/xenia-rs/audit-runs/phase-w-wedge-reattack/ours-postfix.jsonl"
|
||||
ours_evts = []
|
||||
with open(OURS_INPUT, "r") as f:
|
||||
for line in f:
|
||||
if f'"tid":13' not in line:
|
||||
continue
|
||||
try:
|
||||
ev = json.loads(line)
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if ev.get("tid") != 13:
|
||||
continue
|
||||
ours_evts.append(ev)
|
||||
|
||||
print(f"ours tid=13: {len(ours_evts)} events")
|
||||
if ours_evts:
|
||||
print(f" first host_ns: {ours_evts[0]['host_ns']/1e9:.4f}s")
|
||||
print(f" last host_ns: {ours_evts[-1]['host_ns']/1e9:.4f}s")
|
||||
|
||||
ours_sum = Counter()
|
||||
for ev in ours_evts:
|
||||
if ev["kind"] == "kernel.call":
|
||||
ours_sum[ev["payload"].get("name", "?")] += 1
|
||||
|
||||
print(f"\n=== ours tid=13 kernel.calls ({len(ours_sum)} unique) ===")
|
||||
for n, c in ours_sum.most_common(40):
|
||||
print(f" {c:5d} {n}")
|
||||
|
||||
# Differential table.
|
||||
all_names = set(sum_calls.keys()) | set(ours_sum.keys())
|
||||
print(f"\n=== Differential canary tid=17 vs ours tid=13 ===")
|
||||
print(f"{'kernel.call':<45s} {'canary':>8s} {'ours':>8s} {'delta':>8s}")
|
||||
diffs = []
|
||||
for n in sorted(all_names):
|
||||
cc = sum_calls.get(n, 0)
|
||||
oc = ours_sum.get(n, 0)
|
||||
diffs.append((cc - oc, n, cc, oc))
|
||||
diffs.sort(key=lambda x: -abs(x[0]))
|
||||
for delta, n, cc, oc in diffs[:80]:
|
||||
print(f" {n:<45s} {cc:>8d} {oc:>8d} {delta:>+8d}")
|
||||
|
||||
with open(os.path.join(OUTDIR, "differential-canary-tid17-vs-ours-tid13.txt"), "w") as f:
|
||||
f.write(f"Differential canary tid=17 (sub_821748F0 worker) vs ours tid=13\n\n")
|
||||
f.write(f"canary tid=17 total events: {len(evts)}, ours tid=13 total: {len(ours_evts)}\n")
|
||||
f.write(f"canary tid=17 duration: 1.9378s..2.0918s (154ms, terminates)\n")
|
||||
f.write(f"ours tid=13 duration: until wedge, never terminates\n\n")
|
||||
f.write(f"{'kernel.call':<45s} {'canary':>8s} {'ours':>8s} {'delta':>8s}\n")
|
||||
for delta, n, cc, oc in diffs:
|
||||
f.write(f" {n:<45s} {cc:>8d} {oc:>8d} {delta:>+8d}\n")
|
||||
Reference in New Issue
Block a user