# 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.