mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-13 06:20:26 +02:00
Crash screen: Add a very dangerous and inaccurate "Resume" function.
Not sure if there's much point really but maybe..
This commit is contained in:
1 parent
a550aacf96
commit
6c8ee35826
4 files changed
+56
-7
No files matched your search
+24
-2
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Common/MachineContext.h"
|
||||
|
||||
#if PPSSPP_ARCH(AMD64) || PPSSPP_ARCH(X86)
|
||||
@@ -37,9 +40,13 @@
|
||||
namespace Memory {
|
||||
|
||||
static int64_t g_numReportedBadAccesses = 0;
|
||||
const uint8_t *g_lastCrashAddress;
|
||||
std::unordered_set<const uint8_t *> g_ignoredAddresses;
|
||||
|
||||
void MemFault_Init() {
|
||||
g_numReportedBadAccesses = 0;
|
||||
g_lastCrashAddress = nullptr;
|
||||
g_ignoredAddresses.clear();
|
||||
}
|
||||
|
||||
#ifdef MACHINE_CONTEXT_SUPPORTED
|
||||
@@ -67,10 +74,21 @@ static bool DisassembleNativeAt(const uint8_t *codePtr, int instructionSize, std
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MemFault_MayBeResumable() {
|
||||
return g_lastCrashAddress != nullptr;
|
||||
}
|
||||
|
||||
void MemFault_IgnoreLastCrash() {
|
||||
g_ignoredAddresses.insert(g_lastCrashAddress);
|
||||
}
|
||||
|
||||
bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
SContext *context = (SContext *)ctx;
|
||||
const uint8_t *codePtr = (uint8_t *)(context->CTX_PC);
|
||||
|
||||
// We set this later if we think it can be resumed from.
|
||||
g_lastCrashAddress = nullptr;
|
||||
|
||||
// TODO: Check that codePtr is within the current JIT space.
|
||||
bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr);
|
||||
if (!inJitSpace) {
|
||||
@@ -91,6 +109,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// OK, a guest executable did a bad access. Take care of it.
|
||||
|
||||
uint32_t guestAddress = hostAddress - baseAddress;
|
||||
@@ -149,7 +168,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
type = MemoryExceptionType::UNKNOWN;
|
||||
}
|
||||
|
||||
if (success && g_Config.bIgnoreBadMemAccess) {
|
||||
if (success && (g_Config.bIgnoreBadMemAccess || g_ignoredAddresses.find(codePtr) != g_ignoredAddresses.end())) {
|
||||
if (!info.isMemoryWrite) {
|
||||
// It was a read. Fill the destination register with 0.
|
||||
// TODO
|
||||
@@ -165,7 +184,10 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||
uint32_t approximatePC = currentMIPS->pc;
|
||||
Core_MemoryExceptionInfo(guestAddress, approximatePC, type, infoString);
|
||||
|
||||
// Redirect execution to a crash handler that will exit the game immediately.
|
||||
// There's a small chance we can resume from this type of crash.
|
||||
g_lastCrashAddress = codePtr;
|
||||
|
||||
// Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately.
|
||||
context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler();
|
||||
ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation. Info:\n%s", guestAddress, (void *)hostAddress, infoString.c_str());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user