Debugger: Fixed crashes when CPU is running in unmapped memory regions

This commit is contained in:
Sour 2020-04-19 19:36:47 -04:00
parent caa8a6ac25
commit 8af0df2ecf
3 changed files with 44 additions and 22 deletions

View file

@ -783,33 +783,36 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
_prevInstructionCycle = _curInstructionCycle; _prevInstructionCycle = _curInstructionCycle;
_curInstructionCycle = (int64_t)_cpu->GetCycleCount(); _curInstructionCycle = (int64_t)_cpu->GetCycleCount();
_disassembler->BuildCache(addressInfo, addr, false, true);
if(absoluteAddr >= 0) { if(absoluteAddr >= 0) {
_codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Code); _codeDataLogger->SetFlag(absoluteAddr, CdlPrgFlags::Code);
} }
if(_disassembler->IsJump(value)) { if(addressInfo.Address >= 0) {
uint16_t targetPc = _disassembler->GetDisassemblyInfo(addressInfo).GetJumpDestination(_cpu->GetPC(), _memoryManager.get()); _disassembler->BuildCache(addressInfo, addr, false, true);
AddressTypeInfo addressInfo;
GetAbsoluteAddressAndType(targetPc, &addressInfo); if(_disassembler->IsJump(value)) {
if(addressInfo.Address >= 0 && addressInfo.Type == AddressType::PrgRom) { uint16_t targetPc = _disassembler->GetDisassemblyInfo(addressInfo).GetJumpDestination(_cpu->GetPC(), _memoryManager.get());
if(value == 0x20) {
//JSR, mark target as a sub entry point AddressTypeInfo targetAddr;
_disassembler->BuildCache(addressInfo, targetPc, true, false); GetAbsoluteAddressAndType(targetPc, &targetAddr);
_functionEntryPoints.emplace(addressInfo.Address); if(targetAddr.Address >= 0 && targetAddr.Type == AddressType::PrgRom) {
_codeDataLogger->SetFlag(addressInfo.Address, CdlPrgFlags::SubEntryPoint); if(value == 0x20) {
} else { //JSR, mark target as a sub entry point
//Only mark as jump target if not marked as sub entry point _disassembler->BuildCache(targetAddr, targetPc, true, false);
_codeDataLogger->SetFlag(addressInfo.Address, CdlPrgFlags::JumpTarget); _functionEntryPoints.emplace(targetAddr.Address);
_codeDataLogger->SetFlag(targetAddr.Address, CdlPrgFlags::SubEntryPoint);
} else {
//Only mark as jump target if not marked as sub entry point
_codeDataLogger->SetFlag(targetAddr.Address, CdlPrgFlags::JumpTarget);
}
} }
} }
_performanceTracker->ProcessCpuExec(addressInfo);
} }
ProcessStepConditions(addr); ProcessStepConditions(addr);
_performanceTracker->ProcessCpuExec(addressInfo);
BreakSource breakSource = BreakSource::Unspecified; BreakSource breakSource = BreakSource::Unspecified;
if(value == 0 && CheckFlag(DebuggerFlags::BreakOnBrk)) { if(value == 0 && CheckFlag(DebuggerFlags::BreakOnBrk)) {
Step(1); Step(1);
@ -845,7 +848,11 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
if(_codeRunner && _codeRunner->IsRunning() && addr >= 0x3000 && addr < 0x4000) { if(_codeRunner && _codeRunner->IsRunning() && addr >= 0x3000 && addr < 0x4000) {
disassemblyInfo = _codeRunner->GetDisassemblyInfo(addr); disassemblyInfo = _codeRunner->GetDisassemblyInfo(addr);
} else { } else {
disassemblyInfo = _disassembler->GetDisassemblyInfo(addressInfo); if(addressInfo.Address >= 0) {
disassemblyInfo = _disassembler->GetDisassemblyInfo(addressInfo);
} else {
disassemblyInfo.Initialize(addr, _memoryManager.get(), false);
}
} }
_traceLogger->Log(_debugState, disassemblyInfo, operationInfo); _traceLogger->Log(_debugState, disassemblyInfo, operationInfo);
} else { } else {

View file

@ -163,6 +163,21 @@ void DisassemblyInfo::Initialize(uint8_t* opPointer, bool isSubEntryPoint)
_isSubExitPoint = opCode == 0x40 || opCode == 0x60; _isSubExitPoint = opCode == 0x40 || opCode == 0x60;
} }
void DisassemblyInfo::Initialize(uint16_t addr, MemoryManager* memoryManager, bool isSubEntryPoint)
{
_isSubEntryPoint = isSubEntryPoint;
uint8_t opCode = memoryManager->DebugRead(addr);
_opSize = DisassemblyInfo::OPSize[opCode];
_opMode = DisassemblyInfo::OPMode[opCode];
for(uint32_t i = 0; i < _opSize; i++) {
_byteCode[i] = memoryManager->DebugRead(addr + i);
}
_isSubExitPoint = opCode == 0x40 || opCode == 0x60;
}
void DisassemblyInfo::SetSubEntryPoint() void DisassemblyInfo::SetSubEntryPoint()
{ {
_isSubEntryPoint = true; _isSubEntryPoint = true;

View file

@ -1,11 +1,10 @@
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
#include <unordered_map> #include <unordered_map>
#include "Types.h"
class MemoryManager; class MemoryManager;
class LabelManager; class LabelManager;
struct State;
enum class AddrMode;
class DisassemblyInfo class DisassemblyInfo
{ {
@ -16,17 +15,18 @@ public:
static bool IsUnofficialCode[256]; static bool IsUnofficialCode[256];
private: private:
uint8_t _byteCode[3]; uint8_t _byteCode[3] = {};
bool _isSubEntryPoint = false; bool _isSubEntryPoint = false;
bool _isSubExitPoint = false; bool _isSubExitPoint = false;
uint32_t _opSize = 0; uint32_t _opSize = 0;
AddrMode _opMode; AddrMode _opMode = AddrMode::None;
public: public:
DisassemblyInfo(); DisassemblyInfo();
DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint); DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint);
void Initialize(uint8_t * opPointer, bool isSubEntryPoint); void Initialize(uint8_t * opPointer, bool isSubEntryPoint);
void Initialize(uint16_t addr, MemoryManager* memoryManager, bool isSubEntryPoint);
void SetSubEntryPoint(); void SetSubEntryPoint();