[WIP] Audio/threading fixes + crash investigation; NEW ORACLE: crash is ours not the game
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 1m34s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 1m34s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped
Snapshot for handoff. Contains the mission-audio + threading fixes and the
crash-investigation instrumentation (all diagnostic cvars default-OFF).
Fixes (behavioral):
- threading_posix.cc: reap-once guard on PosixCondition<Thread>::post_execution
(double pthread_join at mission teardown -> fault loop -> audio death + freeze).
- xma_decoder.cc: work_event_->Set() in Pause() so the idle XMA worker observes
paused_ and signals pause_fence_ (Pause() deadlock -> permanent audio death).
- audio_system / xma_context_master / xboxkrnl_audio / apu_flags / alsa: mission
audio keepalive + guest_audio_flags + watchdogs.
Instrumentation (additive, default-off): xboxkrnl_debug cache-throw diag +
guest-catch dispatcher, xex_module PE/PDATA/EH scans, kernel_state mem_watch
(NOTE: mem_watch DEFAULTS TRUE -- an always-on host poll thread; prime crash suspect).
NEW ORACLE (see HANDOFF-crash-oracle-2026-07-16.md): stock 6e5b8324f built with
our toolchain + zero custom code = NO crash, NO sound-stop, plays the Ready Room.
=> the Ready-Room out_of_range crash is introduced by THESE changes, not the game
and not the (LTO-broken) build chain. Bisection plan + suspect ranking in the note.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1388,7 +1388,18 @@ bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) {
|
||||
uint32_t base_page_number = (base_address - heap_base_) / page_size_;
|
||||
auto base_page_entry = page_table_[base_page_number];
|
||||
if (base_page_entry.base_address != base_page_number) {
|
||||
XELOGE("BaseHeap::Release failed because address is not a region start");
|
||||
// The guest asked us to free something we refuse to free -- it then
|
||||
// believes that memory is gone while we still hold it. Say WHAT we
|
||||
// refused: the address, the region we think it belongs to, and whether
|
||||
// the page is even allocated. (Was a bare message with no data.)
|
||||
const uint32_t owner_addr =
|
||||
heap_base_ + base_page_entry.base_address * page_size_;
|
||||
XELOGE(
|
||||
"BaseHeap::Release failed because address is not a region start: "
|
||||
"addr={:08X} heap_base={:08X} page={} owning_region_start={:08X} "
|
||||
"region_page_count={} state={:02X}",
|
||||
base_address, heap_base_, base_page_number, owner_addr,
|
||||
base_page_entry.region_page_count, base_page_entry.state);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user