diff --git a/Core/Core.cpp b/Core/Core.cpp index fbecf8e4a0ad..0993de16c5ae 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -455,7 +455,7 @@ void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type) { } } -void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo) { +void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo, bool forceReport) { const char *desc = MemoryExceptionTypeAsString(type); // In jit, we only flush PC when bIgnoreBadMemAccess is off. if (g_Config.iCpuCore == (int)CPUCore::JIT && g_Config.bIgnoreBadMemAccess) { @@ -464,7 +464,7 @@ void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std WARN_LOG(MEMMAP, "%s: Invalid address %08x PC %08x LR %08x %s", desc, address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA], additionalInfo.c_str()); } - if (!g_Config.bIgnoreBadMemAccess) { + if (!g_Config.bIgnoreBadMemAccess || forceReport) { ExceptionInfo &e = g_exceptionInfo; e = {}; e.type = ExceptionType::MEMORY; @@ -476,6 +476,7 @@ void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std } } +// Can't be ignored void Core_ExecException(u32 address, u32 pc, ExecExceptionType type) { const char *desc = ExecExceptionTypeAsString(type); WARN_LOG(MEMMAP, "%s: Invalid destination %08x PC %08x LR %08x", desc, address, pc, currentMIPS->r[MIPS_REG_RA]); diff --git a/Core/Core.h b/Core/Core.h index d706e7afec78..a807f61b9ab4 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -103,7 +103,7 @@ enum class ExecExceptionType { // Separate one for without info, to avoid having to allocate a string void Core_MemoryException(u32 address, u32 pc, MemoryExceptionType type); -void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo); +void Core_MemoryExceptionInfo(u32 address, u32 pc, MemoryExceptionType type, std::string additionalInfo, bool forceReport); void Core_ExecException(u32 address, u32 pc, ExecExceptionType type); void Core_Break(u32 pc); diff --git a/Core/MemFault.cpp b/Core/MemFault.cpp index c7df04669744..317cb875a835 100644 --- a/Core/MemFault.cpp +++ b/Core/MemFault.cpp @@ -280,8 +280,9 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) { } } else { // Either bIgnoreBadMemAccess is off, or we failed recovery analysis. + // We can't ignore this memory access. uint32_t approximatePC = currentMIPS->pc; - Core_MemoryExceptionInfo(guestAddress, approximatePC, type, infoString); + Core_MemoryExceptionInfo(guestAddress, approximatePC, type, infoString, true); // There's a small chance we can resume from this type of crash. g_lastCrashAddress = codePtr; diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index c0579ca7e357..e44cca44b661 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -1199,6 +1199,9 @@ static void DrawCrashDump(UIContext *ctx) { ctx->PushScissor(Bounds(x, y, columnWidth, height)); + + INFO_LOG(SYSTEM, "DrawCrashDump (%d %d %d %d)", x, y, columnWidth, height); + snprintf(statbuf, sizeof(statbuf), R"(%s %s (%s) %s (%s) @@ -1565,6 +1568,10 @@ void EmuScreen::renderUI() { const ExceptionInfo &info = Core_GetExceptionInfo(); if (info.type != ExceptionType::NONE) { DrawCrashDump(ctx); + } else { + // We're somehow in ERROR or STEPPING without a crash dump. This case is what lead + // to the bare "Resume" and "Reset" buttons without a crash dump before, in cases + // where we were unable to ignore memory errors. } }