[Audit] round 24: signal-path probes (XEvent::Set + IO + NtDuplicateObject)
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>
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_ob.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/cpu/thread_state.h"
|
||||
#include "xenia/kernel/kernel_flags.h"
|
||||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_threading.h"
|
||||
@@ -398,6 +400,14 @@ dword_result_t NtDuplicateObject_entry(dword_t handle, lpdword_t new_handle_ptr,
|
||||
X_STATUS result =
|
||||
kernel_state()->object_table()->DuplicateHandle(handle, &new_handle);
|
||||
|
||||
if (cvars::audit_handle_lifecycle) {
|
||||
uint32_t lr = static_cast<uint32_t>(cpu::ThreadState::Get()->context()->lr);
|
||||
XELOGKERNEL(
|
||||
"AUDIT-HLC NtDuplicateObject src={:08X} dst={:08X} options={:08X} "
|
||||
"lr={:08X}",
|
||||
uint32_t(handle), uint32_t(new_handle), uint32_t(options), lr);
|
||||
}
|
||||
|
||||
if (new_handle_ptr) {
|
||||
*new_handle_ptr = new_handle;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user