diff --git a/src/xenia/cpu/cpu_flags.cc b/src/xenia/cpu/cpu_flags.cc index 3ff067e15..467bc34b2 100644 --- a/src/xenia/cpu/cpu_flags.cc +++ b/src/xenia/cpu/cpu_flags.cc @@ -57,3 +57,9 @@ DEFINE_bool(break_condition_truncate, true, "truncate value to 32-bits", "CPU"); DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests.", "CPU"); + +DEFINE_string(memory_dump_path, "", + "If non-empty, dump guest memory (heaps v0/v40/v80/v90/phys) to " + "this path on first XamNotifyCreateListener call. Format = " + "Memory::Save() raw (no signature/header).", + "CPU"); diff --git a/src/xenia/cpu/cpu_flags.h b/src/xenia/cpu/cpu_flags.h index 38c4f98ba..02f15d5b2 100644 --- a/src/xenia/cpu/cpu_flags.h +++ b/src/xenia/cpu/cpu_flags.h @@ -35,4 +35,6 @@ DECLARE_bool(break_condition_truncate); DECLARE_bool(break_on_debugbreak); +DECLARE_string(memory_dump_path); + #endif // XENIA_CPU_CPU_FLAGS_H_ diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_audio.cc index a0c7651b2..2e2b3741c 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_audio.cc @@ -14,6 +14,14 @@ #include "xenia/kernel/xboxkrnl/xboxkrnl_private.h" #include "xenia/xbox.h" +#include +#include "xenia/base/byte_stream.h" +#include "xenia/base/filesystem.h" +#include "xenia/base/logging.h" +#include "xenia/base/mapped_memory.h" +#include "xenia/cpu/cpu_flags.h" +#include "xenia/memory.h" + DECLARE_uint32(audio_flag); namespace xe { @@ -101,6 +109,29 @@ dword_result_t XAudioSubmitRenderDriverFrame_entry(lpunknown_t driver_ptr, kernel_state()->memory()->TranslateVirtual(samples_ptr); audio_system->SubmitFrame(driver_ptr.guest_address() & 0x0000FFFF, samples); + // AUDIT-024A: dump guest memory on first XAudioSubmitRenderDriverFrame call. + static std::atomic dumped{false}; + bool expected = false; + if (!cvars::memory_dump_path.empty() && + dumped.compare_exchange_strong(expected, true)) { + std::filesystem::path path(cvars::memory_dump_path); + XELOGI("AUDIT-024A: dumping guest memory to {} (XAudioSubmitRenderDriverFrame)", + cvars::memory_dump_path); + constexpr size_t kReserve = size_t(2) * 1024 * 1024 * 1024; + filesystem::CreateEmptyFile(path); + std::filesystem::resize_file(path, kReserve); + auto map = MappedMemory::Open(path, MappedMemory::Mode::kReadWrite, 0, + kReserve); + if (map) { + ByteStream stream(map->data(), map->size()); + kernel_state()->emulator()->memory()->Save(&stream); + map->Close(stream.offset()); + XELOGI("AUDIT-024A: wrote {} bytes", stream.offset()); + } else { + XELOGE("AUDIT-024A: failed to open dump path"); + } + } + return X_ERROR_SUCCESS; } DECLARE_XBOXKRNL_EXPORT2(XAudioSubmitRenderDriverFrame, kAudio, kImplemented,