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>
121 lines
9.4 KiB
Markdown
121 lines
9.4 KiB
Markdown
# Canary tid-profile catalogue (Phase Non-match Investigation, 2026-05-19)
|
||
|
||
Source: `xenia-canary/build-cross/bin/Windows/Debug/canary-jitter-1.jsonl`
|
||
(4.4 GB, 18,687,353 events, 28 tids, ~90 s wallclock cold run, jitter-1 sample).
|
||
|
||
## Per-tid headline
|
||
|
||
| tid | events | role | first kind | first host_ns | thread.exit |
|
||
|----:|-------:|------|------------|--------------:|:-----------:|
|
||
| 0 | 12 | bootstrap (`schema_version`) | schema_version | 400 | - |
|
||
| 1 | 69k | system (no spawn match) | import.call | 2.160 s | - |
|
||
| 2 | 20k | NtSetEvent service (13,536 ×) | - | 1.681 s | - |
|
||
| 4 | 196k | **XAudio submitter** (26,124 × XAudioSubmitRenderDriverFrame) | - | 1.813 s | - |
|
||
| 6 | 477k | **GUEST MAIN** (Sylpheed main) | - | 0.660 s | - |
|
||
| 7 | 32 | one-shot init (CreateSymbolicLink, ExRegisterTitleTerminate) | - | 1.422 s | - |
|
||
| 8 | 60 | small worker (spawned by tid=6, entry `0x82181830`) | - | 1.426 s | - |
|
||
| 9 | 8.3k | file-IO worker (NtCreateFile/NtOpenFile/NtSetInformationFile, entry `0x8245A5D0`) | - | 1.445 s | - |
|
||
| 10 | 63k | helper (NtCreateEvent/NtCreateSemaphore + ExCreateThread × 2; entry `0x82450A28`) | - | 1.453 s | - |
|
||
| 11 | 61k | NtWaitForMultipleObjectsEx (13,564 ×), entry `0x82457EF0` | - | 1.542 s | - |
|
||
| 12 | 37k | KeWaitForSingleObject (7,380 ×), entry `0x824CD458` | - | 1.602 s | - |
|
||
| 13 | 594k | **Renderer** (12,092 × VdGetSystemCommandBuffer + VdSwap), entry `0x822F1EE0` | - | 1.671 s | - |
|
||
| 14 | **6.15 M** | **XAudio voice-mask poll** (26,126 × XAudioGetVoiceCategoryVolumeChangeMask + KeReleaseSemaphore + KeWaitForSingleObject; 941,976 × IRQL raise/lock/release/lower triplets), entry `0x824D2878` (aff=16) | - | 1.727 s | - |
|
||
| 15 | **4.78 M** | **XAudio sister** (786,872 × IRQL raise; 26,126 × KeWaitForSingleObject; light KeSetEvent), entry `0x824D2940` (aff=32) | - | 1.728 s | - |
|
||
| 16 | 1.80 M | **XMA decoder / XMACreateContext** (196,976 × RtlEnterCS, 12,072 × NtWaitForSingleObjectEx), entry `0x82178950` | - | 1.932 s | - |
|
||
| 17 | 4.1k | helper (spawns tid=18 via `0x821C4AD0`), entry `0x821748F0` | - | 1.938 s | exit @ 2.092 s, code=0 |
|
||
| 18 | 33k | helper (RtlInitAnsi, NtCreateFile, NtDuplicateObject; spawns 2× `0x822C6870`), entry `0x821C4AD0` | - | 1.959 s | exit @ 2.870 s, code=1 |
|
||
| 19,20 | 9 each | tiny short-lived threads (RtlEnterCS + NtWaitForSingleObjectEx) | - | 1.962/1.963 s | - |
|
||
| 21 | 1.00 M | **NtWaitForMultipleObjectsEx worker** (223,636 ×), entry `0x824563E0` | - | 2.103 s | - |
|
||
| 22 | 51 | tiny worker (entry `0x82170430`) | - | 2.120 s | - |
|
||
| 23 | 17 | tiny (entry `0x823DDE30`) | - | 2.144 s | - |
|
||
| 24,25 | 8 each | tiny (entry `0x823DDB50`) | - | 2.145/2.146 s | - |
|
||
| 26 | 6.7k | helper-second-call of `0x821748F0` (NtYieldExecution × 1,282), entry `0x821748F0` | - | 10.080 s | exit @ 10.280 s, code=0 |
|
||
| 27 | 36k | **sub_825070F0 worker 1** (entry `0x82506558`, ctx `0xBCE251C0`, slot 36 of dispatcher vtable) | - | 10.707 s | - |
|
||
| 28 | **3.26 M** | **sub_825070F0 worker 0** (entry `0x82506528`, ctx `0xBCE251C0`, slot 35; 1.07 M × RtlEnterCS, 530 × NtReadFile) | - | 10.707 s | - |
|
||
| 29 | 91k | **sub_825070F0 worker 2** (entry `0x82506588`, ctx `0xBCE251C0`, slot 37; 7,252 × KeWait + heavy IRQL) | - | 12.375 s | - |
|
||
| - | - | **sub_825070F0 worker 3 (`0x825065B8`) NEVER STARTED** in this 90 s window | - | - | - |
|
||
|
||
## Spawn chain (chronological)
|
||
|
||
All `thread.create` events are emitted on the parent thread (per `event_log.cc:312-326`); `parent_tid` in payload duplicates the `tid` field.
|
||
|
||
| host_ns | spawner | entry_pc | ctx_ptr | aff | stk | susp | child tid | notes |
|
||
|--------:|--------:|---------:|--------:|----:|----:|:----:|----------:|-------|
|
||
| 1.425 s | 6 | `0x82181830` | `0x828F3D08` | 0 | 131,072 | F | 8 | first guest spawn |
|
||
| 1.444 s | 6 | `0x8245A5D0` | `0x828F4838` | 0 | 65,536 | F | 9 | file IO |
|
||
| 1.453 s | 6 | `0x82450A28` | `0x828F3B68` | 0 | 262,144 | F | 10 | helper |
|
||
| 1.542 s | 10 | `0x82457EF0` | `0x828F3B08` | 0 | 65,536 | F | 11 | tid=10 spawns tid=11 |
|
||
| 1.601 s | 6 | `0x824CD458` | `0xBE56BB3C` | 4 | 32,768 | F | 12 | KeWait worker |
|
||
| 1.670 s | 6 | `0x822F1EE0` | `0xBCE24A40` | 0 | 524,288 | **T** | 13 | renderer |
|
||
| 1.726 s | 6 | `0x824D2878` | `0x00000000` | 16 | 524,288 | **T** | 14 | **XAudio (huge)** |
|
||
| 1.727 s | 6 | `0x824D2940` | `0x00000000` | 32 | 524,288 | **T** | 15 | XAudio sister |
|
||
| 1.931 s | 6 | `0x82178950` | `0x828F3EC0` | 0 | 65,536 | F | 16 | XMA decoder |
|
||
| 1.935 s | 6 | `0x821748F0` | `0xBC365620` | 0 | 524,288 | **T** | 17 | spawner of 18 |
|
||
| 1.958 s | 17 | `0x821C4AD0` | `0xBCA44B60` | 0 | 65,536 | F | 18 | tid=17 spawns tid=18 |
|
||
| 1.962 s | 18 | `0x822C6870` | `0x828F3300` | 0 | 196,608 | **T** | 19 | tid=18 spawns 19 |
|
||
| 1.962 s | 18 | `0x822C6870` | `0x828F3300` | 0 | 196,608 | **T** | 20 | tid=18 spawns 20 |
|
||
| 2.103 s | 6 | `0x824563E0` | `0x828F3E70` | 0 | 16,384 | F | 21 | NtWaitForMultipleObjectsEx worker |
|
||
| 2.120 s | 6 | `0x82170430` | `0x828F4070` | 0 | 65,536 | F | 22 | tiny |
|
||
| 2.143 s | 6 | `0x823DDE30` | `0x828F3C4C` | 0 | 65,536 | F | 23 | tiny |
|
||
| 2.144 s | 6 | `0x823DDB50` | `0x828F3C88` | 0 | 524,288 | **T** | 24 | tiny |
|
||
| 2.145 s | 6 | `0x823DDB50` | `0x828F3C88` | 0 | 524,288 | **T** | 25 | tiny |
|
||
| 10.079 s | 6 | `0x821748F0` | `0xBC366EE0` | 0 | 524,288 | **T** | 26 | repeat of earlier spawn (different ctx) |
|
||
| **10.383 s** | **6** | **`0x82506528`** | **`0xBCE251C0`** | **0** | **65,536** | **T** | **28** | **sub_825070F0 worker 0** |
|
||
| **10.383 s** | **6** | **`0x82506558`** | **`0xBCE251C0`** | **0** | **65,536** | **T** | **27** | **sub_825070F0 worker 1** |
|
||
| **10.384 s** | **6** | **`0x82506588`** | **`0xBCE251C0`** | **0** | **65,536** | **T** | **29** | **sub_825070F0 worker 2** |
|
||
| **10.384 s** | **6** | **`0x825065B8`** | **`0xBCE251C0`** | **0** | **65,536** | **T** | (none) | **sub_825070F0 worker 3 unresumed** |
|
||
|
||
The 4 final spawns are **exactly** the AUDIT-058/063-predicted `sub_825070F0` worker batch (per dossier
|
||
`xenia-rs/docs/functions/sub_825070F0.md`: worker entries `0x82506528/58/88/B8`).
|
||
|
||
## Ours's spawn behaviour (Phase W ours-postfix.jsonl)
|
||
|
||
Ours emits **10 thread.create** events vs canary's **23**. Ours stops after spawn #10 (`0x821748F0` at 1.727 s).
|
||
|
||
| host_ns | spawner | entry_pc | ctx_ptr | stk | susp |
|
||
|--------:|--------:|---------:|--------:|----:|:----:|
|
||
| 0.469 s | 1 | `0x82181830` | `0x828F3D08` | 131,072 | F |
|
||
| 0.470 s | 1 | `0x8245A5D0` | `0x828F4838` | 65,536 | F |
|
||
| 0.471 s | 1 | `0x82450A28` | `0x828F3B68` | 262,144 | F |
|
||
| 0.488 s | **5** | `0x82457EF0` | `0x828F3B08` | 65,536 | F |
|
||
| 0.495 s | 1 | `0x824CD458` | `0x42453B3C` | 32,768 | F |
|
||
| 1.413 s | 1 | `0x822F1EE0` | `0x40D0CA40` | 0 | **T** |
|
||
| 1.626 s | 1 | `0x824D2878` | `0x00000000` | 0 | **T** |
|
||
| 1.626 s | 1 | `0x824D2940` | `0x00000000` | 0 | **T** |
|
||
| 1.727 s | 1 | `0x82178950` | `0x828F3EC0` | 65,536 | F |
|
||
| 1.727 s | 1 | `0x821748F0` | `0x4024D640` | 0 | **T** |
|
||
|
||
After spawn #10, ours **never produces another `thread.create`** in the 50 M-event trace window (~3 s wallclock window per ours's faster clock). The 13 subsequent canary spawns (including the critical 4 `sub_825070F0` workers at 10.38 s) are missing.
|
||
|
||
Also note ctx-ptr divergence: ours emits `0x42453B3C` / `0x40D0CA40` / `0x4024D640` where canary emits `0xBE56BB3C` / `0xBCE24A40` / `0xBC365620` — these are the same physical RAM offset displayed with different host-side base addresses (`0xBC000000` canary mapping vs ours's `0x40000000` mapping). Not a real divergence.
|
||
|
||
## XAudio context: `0xBCE251C0`
|
||
|
||
Search count across the 4.4 GB canary jsonl: **4 occurrences**, all in the 4 `sub_825070F0` worker spawn `ctx_ptr` fields.
|
||
Same address in ours-postfix.jsonl: **0 occurrences**. Ours **never allocates the dispatcher object** that lives at this address. Per the dossier, this is the XAudio2 / `XAudio*` master-voice dispatcher object whose vtable is `0x8200A208` (slot 1 → `sub_825070F0`).
|
||
|
||
## sub_825070F0 vtable dispatch confirmation
|
||
|
||
Per `sylpheed.db`:
|
||
- `sub_825070F0` is at vtable `0x8200A208` slot 1 (anonymous class `ANON_Class_713383D7`).
|
||
- It is also at vtable `0x8200A928` slot 1 (a sibling/derived class with the same layout).
|
||
- **Zero `vptr_writes` rows** target either `0x8200A208` or `0x8200A928`.
|
||
- **Zero `xrefs`** with `target=0x8200A208` or `0x8200A928`.
|
||
- **Zero `indirect_dispatch_candidates`** mapping any `bctrl` site to these vtables.
|
||
- **Zero instructions** with operand text `200A208` or `200A928` (no lis/addi/lis/ori pair).
|
||
|
||
This confirms AUDIT-067's "the vtable is installed host-side" assessment: there is no static guest reference that materialises this vtable address. The object pointer must come from a host shim (allocator, `XAudio2*` API wrapper, etc.) or via a TOC-style load that the static analyser doesn't model.
|
||
|
||
## sub_825070F0 internals (xrefs in `[0x825070F0, 0x825073DC)`)
|
||
|
||
The function performs four nearly-identical spawn blocks at PCs `0x825071F8 / 0x82507244 / 0x82507290 / 0x825072DC`. Each block:
|
||
|
||
```
|
||
addi rN, r0, 0x82506528 (or +0x30, +0x60, +0x90) ; ref to worker entry
|
||
bl sub_824AA388 ; spawn helper (probably wraps ExCreateThread)
|
||
bne ... ; success check
|
||
... vtable bctrl chains to set up worker state ...
|
||
```
|
||
|
||
So `sub_825070F0` calls `sub_824AA388` 4 times in sequence, each with a different `ANON_Class_713383D7` slot pointer. `sub_824AA388` is the actual ExCreateThread wrapper.
|