mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-10-07 10:53:31 +00:00
Merge pull request #16636 from unknownbrackets/exception-safety
Crash: Ensure we never handle faults in faults
This commit is contained in:
commit
d4f5bff360
@ -427,12 +427,20 @@ bool Arm64Jit::DescribeCodePtr(const u8 *ptr, std::string &name) {
|
|||||||
name = "loadStaticRegisters";
|
name = "loadStaticRegisters";
|
||||||
else {
|
else {
|
||||||
u32 addr = blocks.GetAddressFromBlockPtr(ptr);
|
u32 addr = blocks.GetAddressFromBlockPtr(ptr);
|
||||||
std::vector<int> numbers;
|
// Returns 0 when it's valid, but unknown.
|
||||||
blocks.GetBlockNumbersFromAddress(addr, &numbers);
|
if (addr == 0) {
|
||||||
if (!numbers.empty()) {
|
name = "(unknown or deleted block)";
|
||||||
const JitBlock *block = blocks.GetBlock(numbers[0]);
|
return true;
|
||||||
|
} else if (addr != (u32)-1) {
|
||||||
|
name = "(outside space)";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int number = blocks.GetBlockNumberFromAddress(addr);
|
||||||
|
if (number != -1) {
|
||||||
|
const JitBlock *block = blocks.GetBlock(number);
|
||||||
if (block) {
|
if (block) {
|
||||||
name = StringFromFormat("(block %d at %08x)", numbers[0], block->originalAddress);
|
name = StringFromFormat("(block %d at %08x)", number, block->originalAddress);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,6 +375,15 @@ void JitBlockCache::GetBlockNumbersFromAddress(u32 em_address, std::vector<int>
|
|||||||
block_numbers->push_back(i);
|
block_numbers->push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int JitBlockCache::GetBlockNumberFromAddress(u32 em_address) {
|
||||||
|
for (int i = 0; i < num_blocks_; i++) {
|
||||||
|
if (blocks_[i].ContainsAddress(em_address))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
u32 JitBlockCache::GetAddressFromBlockPtr(const u8 *ptr) const {
|
u32 JitBlockCache::GetAddressFromBlockPtr(const u8 *ptr) const {
|
||||||
if (!codeBlock_->IsInSpace(ptr))
|
if (!codeBlock_->IsInSpace(ptr))
|
||||||
return (u32)-1;
|
return (u32)-1;
|
||||||
|
@ -143,6 +143,8 @@ public:
|
|||||||
// Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap.
|
// Returns a list of block numbers - only one block can start at a particular address, but they CAN overlap.
|
||||||
// This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime.
|
// This one is slow so should only be used for one-shots from the debugger UI, not for anything during runtime.
|
||||||
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
|
void GetBlockNumbersFromAddress(u32 em_address, std::vector<int> *block_numbers);
|
||||||
|
// Similar to above, but only the first matching address.
|
||||||
|
int GetBlockNumberFromAddress(u32 em_address);
|
||||||
int GetBlockNumberFromEmuHackOp(MIPSOpcode inst, bool ignoreBad = false) const;
|
int GetBlockNumberFromEmuHackOp(MIPSOpcode inst, bool ignoreBad = false) const;
|
||||||
|
|
||||||
u32 GetAddressFromBlockPtr(const u8 *ptr) const;
|
u32 GetAddressFromBlockPtr(const u8 *ptr) const;
|
||||||
|
@ -44,6 +44,7 @@ namespace Memory {
|
|||||||
static int64_t g_numReportedBadAccesses = 0;
|
static int64_t g_numReportedBadAccesses = 0;
|
||||||
const uint8_t *g_lastCrashAddress;
|
const uint8_t *g_lastCrashAddress;
|
||||||
MemoryExceptionType g_lastMemoryExceptionType;
|
MemoryExceptionType g_lastMemoryExceptionType;
|
||||||
|
static bool inCrashHandler = false;
|
||||||
|
|
||||||
std::unordered_set<const uint8_t *> g_ignoredAddresses;
|
std::unordered_set<const uint8_t *> g_ignoredAddresses;
|
||||||
|
|
||||||
@ -88,6 +89,10 @@ static bool DisassembleNativeAt(const uint8_t *codePtr, int instructionSize, std
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
||||||
|
if (inCrashHandler)
|
||||||
|
return false;
|
||||||
|
inCrashHandler = true;
|
||||||
|
|
||||||
SContext *context = (SContext *)ctx;
|
SContext *context = (SContext *)ctx;
|
||||||
const uint8_t *codePtr = (uint8_t *)(context->CTX_PC);
|
const uint8_t *codePtr = (uint8_t *)(context->CTX_PC);
|
||||||
|
|
||||||
@ -100,6 +105,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
|||||||
bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr);
|
bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr);
|
||||||
if (!inJitSpace) {
|
if (!inJitSpace) {
|
||||||
// This is a crash in non-jitted code. Not something we want to handle here, ignore.
|
// This is a crash in non-jitted code. Not something we want to handle here, ignore.
|
||||||
|
inCrashHandler = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +120,10 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
|||||||
bool invalidHostAddress = hostAddress == (uintptr_t)0xFFFFFFFFFFFFFFFFULL;
|
bool invalidHostAddress = hostAddress == (uintptr_t)0xFFFFFFFFFFFFFFFFULL;
|
||||||
if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) {
|
if (hostAddress < baseAddress || hostAddress >= baseAddress + addressSpaceSize) {
|
||||||
// Host address outside - this was a different kind of crash.
|
// Host address outside - this was a different kind of crash.
|
||||||
if (!invalidHostAddress)
|
if (!invalidHostAddress) {
|
||||||
|
inCrashHandler = false;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -182,6 +190,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
|||||||
// Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately.
|
// Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately.
|
||||||
context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler();
|
context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler();
|
||||||
ERROR_LOG(MEMMAP, "Bad execution access detected, halting: %08x (last known pc %08x, host: %p)", targetAddr, currentMIPS->pc, (void *)hostAddress);
|
ERROR_LOG(MEMMAP, "Bad execution access detected, halting: %08x (last known pc %08x, host: %p)", targetAddr, currentMIPS->pc, (void *)hostAddress);
|
||||||
|
inCrashHandler = false;
|
||||||
return true;
|
return true;
|
||||||
} else if (success) {
|
} else if (success) {
|
||||||
if (info.isMemoryWrite) {
|
if (info.isMemoryWrite) {
|
||||||
@ -218,6 +227,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
|
|||||||
context->CTX_PC = (uintptr_t)MIPSComp::jit->GetCrashHandler();
|
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());
|
ERROR_LOG(MEMMAP, "Bad memory access detected! %08x (%p) Stopping emulation. Info:\n%s", guestAddress, (void *)hostAddress, infoString.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inCrashHandler = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1145,13 +1145,7 @@ UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) {
|
|||||||
JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache();
|
JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache();
|
||||||
if (!blockCache)
|
if (!blockCache)
|
||||||
return UI::EVENT_DONE;
|
return UI::EVENT_DONE;
|
||||||
std::vector<int> blockNum;
|
currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc);
|
||||||
blockCache->GetBlockNumbersFromAddress(currentMIPS->pc, &blockNum);
|
|
||||||
if (blockNum.size() > 0) {
|
|
||||||
currentBlock_ = blockNum[0];
|
|
||||||
} else {
|
|
||||||
currentBlock_ = -1;
|
|
||||||
}
|
|
||||||
UpdateDisasm();
|
UpdateDisasm();
|
||||||
return UI::EVENT_DONE;
|
return UI::EVENT_DONE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user