Bring the cvar-gated JSONL extraction tracer (event_log) forward from the
phase-a-tracing line so args/args_resolved + file.read events are
available alongside the GPU draw logging. Purely additive:
- src/xenia/kernel/event_log.{cc,h}: the tracer (auto-globbed into the
kernel target). Tier 1 fills kernel.call args (raw r3..r10) +
args_resolved.path under --phase_a_trace_args; Tier 2 resolves
NtReadFile handle->path via the object table and emits file.read.
- cpu_flags: phase_a_event_log_path / _mem_writes / _trace_args /
_hash_probe / kernel_emit_contention (all default-off).
- shim_utils.h: phase_a_bridge decl + EmitImportAndCallWithCtx/EmitReturn
hooks in the active X::Trampoline, skipped when Enabled() is false.
Deliberately EXCLUDES the Tier-3 hash-probe HIR/emitter trap (the IPFB
name-hash was recovered statically, so the probe is moot). The
phase_a_hash_probe cvar is defined but inert.
Default-off => instrument-current behaviour byte-identical when unused.
Not yet compile-verified against instrument-current's toolchain.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two Linux mission-audio fixes for Project Sylpheed (audio played in
intro/menu but died when a mission finished loading, never returning):
- alsa_audio_driver: when the guest stalls (mission "Preparing for Sortie"
load) and the ring buffer empties, feed silence to keep the PCM alive
instead of sleeping. Previously the small buffer drained, XRUN'd, and
playback never recovered (matches the known "audio muted permanently").
- xconfig: make the guest speaker config a cvar (guest_audio_flags,
default Digital Stereo) instead of hardcoded Dolby Digital surround.
(The practical fix on this box also needed log_mask=13 to stop kernel log
spam starving the audio pipeline during missions — config, not code.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds AUDIT-HLC probes for every path that signals an XEvent or duplicates
its handle, so the round-23 puzzle (waits completing without visible
NtSetEvent/KeSetEvent) can be cross-referenced by underlying X_KEVENT VA
and by primary handle.
* NtCreateEvent_inner: always log kevent_va for handle/VA cross-ref
* XEvent::Set: universal hook prints primary handle + kevent_va + LR;
catches all paths into the event regardless of shim used
* NtSetEvent: extended with PPC back-chain walk for caller's guest_lr
(same idiom as the wait probe), so the signaler function is
immediately identifiable
* NtReadFile / NtReadFileScatter / NtWriteFile: log when signal_event
path fires ev->Set() inline at IO completion (bypasses both
NtSetEvent and KeSetEvent shims)
* CompleteOverlappedEx (kernel_state.cc): log when overlapped event
is signaled at completion
* NtDuplicateObject: log src/dst handle pair (round-24 confirmed silph
event is dup'd before signaling, explaining the handle-mismatch
puzzle between NtSetEvent's `handle=` argument and XEvent::Set's
primary handle())
Result: silph wait at sub_821CB030+0x1B0 on handle F80000A0 is signaled
via NtSetEvent on handle F80000A8 (the duplicate created by sub_8245D9D8
at lr=0x82450DF4 inside the worker chain sub_82450A28 ← 0xA68 ← 0xB68).
Verdict A confirmed: signaler exists and is reachable, but round-17.β
missed it because the search keyed on the wrong handle. No bypass path;
the worker chain is identical between canary and ours-impl, but ours
signals different handles (work-item queue divergence at sub_82452DC0).
Audit-only diagnostic. No semantic changes. Net delta +86 LOC across 7
files. All probes gated on the existing audit_handle_lifecycle cvar
(default off). Tested via Sylpheed boot (35 s, 4 MB log). Audit-handle-
lifecycle-probes branch, local-only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round-14 of AUDIT-2BF (singleton-dump). Pairs with xenia-rs'
--audit-mem-read-hex to emit one comparable XELOGKERNEL line resolving
the bctrl target at sub_822F1AA8+0x90 (PC 0x822F1B4C):
[0x828E1F08] -> singleton instance ptr
[singleton+0] -> vtable
[vtable+0] -> vtable[0] (= first virtual method, bctrl tgt)
[vtable+24] -> vtable[24] (= slot 6, silph chain target)
Two complementary hooks:
1. src/xenia/cpu/backend/x64/x64_emitter.cc: extend
AuditLogJitPrologArgs. New cvar `audit_jit_prolog_mem_dump` (uint32).
When non-zero and an `audit_jit_prolog_pc` fire happens, the host
side dereferences the VA 3 levels deep and emits one
AUDIT-MEM-READ line in the same format ours emits. Defensive
per-level null + VA-range checks.
2. src/xenia/kernel/kernel_state.cc: one-shot dump in
EmulateCPInterruptDPC of the same chain (hard-coded to
0x828E1F08). Useful when audit_jit_prolog_pc isn't set; fires the
first time the CP interrupt path runs (after the singleton ctor
has had time to populate).
Read-only. Both gates default-off; no impact when cvars unset.
~65 LOC total across the two files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two cvar-gated AUDIT-HLC probes for thread-spawn lineage attribution:
1. ExCreateThread_entry shim logs (start_address, start_context, xapi,
flags, kernel lr, guest_lr). guest_lr is recovered via the same
one-frame-up PPC back-chain walk used by the NtWaitForSingleObjectEx
probe (lr saved at [back2 - 8]).
2. XThread::Execute emits (tid, start_address, start_context, xapi) at
the very top so each running thread can be matched back to its
creating ExCreateThread entry by (start_address, start_context).
Gated on the existing cvars::audit_handle_lifecycle; no new cvar.
Pulled in xenia/kernel/kernel_flags.h from xthread.cc to expose the
cvar declaration there.
Used by audit-059 round 12 to enumerate the 23 thread spawns in
canary's 35 s boot, attribute each to its guest_lr caller, and cross-
reference against ours' 10 spawns to identify the 7 missing
spawner functions (including sub_824F7800 which spawns the 4 silph
PKEVENT workers at entry=0x82506528/58/88/B8 via guest_lr=0x824F7B24).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a 41-LOC cvar-gated probe (audit_handle_lifecycle) that emits a one-shot
0x300-byte hexdump of the silph::WorkerCtx context the first time KeSetEvent
fires into the silph UI PKEVENT cluster (0xBCE25200..0xBCE25300 in current
builds). Recovers ctx_base by anchoring on the canonical layout (events at
ctx+0x54/+0x64/+0x74/+0x84 with 16-byte stride; ctx_base = ev_addr - (ev_addr
- 0xBCE251C0)). Also emits an explicit per-slot summary of the 8 candidate
KEVENT headers at +0x54..+0xC4 for sanity.
Produces 48 DUMP rows + 8 slot rows in canary.log on the first triggering
KeSetEvent. Guarded by std::atomic_bool so subsequent fires are silent. Used
by iterate 2.BF context-replication in ours: we need the live [ctx+0] vtable
pointer and the 4 quiet/4 active KEVENT slot config to synthesize a matching
WorkerCtx and spawn the four sub_82506xxx entries.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extend the AUDIT-HLC probes with guest LR capture:
- NtCreateEvent, NtSetEvent, KeSetEvent: log immediate guest LR
(cpu::ThreadState::Get()->context()->lr) so callers can be
attributed to specific guest functions.
- NtWaitForSingleObjectEx entry + _done: also walk one PPC stack
frame up to recover the guest_lr of the wait wrapper's caller
(Xbox 360 EABI: saved LR at [prev_sp - 8], see xenia-rs's
walk_guest_back_chain). lr_enter alone gives only the kernel
wait wrapper return address (e.g. 0x824AC578); guest_lr surfaces
the actual call site.
Still cvar-gated on audit_handle_lifecycle. Used in audit-059 round 4
to map canary handles F8000xxx to ours' 0x12xx wedges via guest LR
matching against silph::UImpl/GamePart cluster.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New cvar `audit_handle_lifecycle` (Auditing group, default false).
When enabled, emits one-line XELOGKERNEL traces tagged AUDIT-HLC at:
NtCreateEvent return, NtSetEvent entry, KeSetEvent entry,
NtWaitForSingleObjectEx entry + completion,
EmulateCPInterruptDPC entry.
Observation-only: zero-overhead when cvar off (single branch + flag
read). Intended for handle disambiguation between xenia-rs and
canary under the Wine cross-build oracle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Thanks to latest change there is no need to use hardcoded nanosleep, so we can go back to previous stuff.
Hopefully it will fix some random issues with audio introduced lately
- Change OddObj to X_DISPATCH_HEADER
- Add unknown X_KWAIT_REASON flag
- Fixed InitializeGuestObject mistake
- Replaces unknowns in kthread using nukernel as reference